Can we only simply recite that the class of java is thread-safe, and that class is not thread-safe?
How is this different from giving a man a fish? Isn't there a way to teach a man to fish? Directly teach us how to judge whether a class is thread-safe?
What is thread safety in java:
it means thread synchronization, that is, when a program accesses a thread-safe method or statement, others can no longer operate on it, and must wait until the end of the access. This thread-safe method to access
what is thread-safe:
if your code is in a process with multiple threads running at the same time, these threads may be running this code at the same time. If the result of each run is the same as the result of a single-threaded run, and the values of other variables are the same as expected, it is thread-safe.
In other words: the interface provided by a class or program is an atomic operation for threads or switching between multiple threads will not lead to ambiguity in the execution result of the interface, that is to say, we do not need to consider the problem of synchronization.
Thread safety problems are caused by global variables and static variables.
If each thread only has read operations on global variables and static variables, but no write operations, generally speaking, this global variable is thread-safe; if multiple threads perform write operations at the same time, thread synchronization generally needs to be considered, otherwise may affect thread safety.
Students who have read the vector source code will know that many of his operations are modified with synchronized, such as his adding elements. (I don't know what synchronized means by Baidu!)
1
2
3
|
public
synchronized
void
addElement(E obj) { modCount++;
ensureCapacityHelper(elementCount +
1
); elementData[elementCount++] = obj;
}
|
And all the operations of HashMap are not decorated with synchronized, it is not as good as his put source code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
V put(K key, V value) {
if
(key ==
null
)
return
putForNullKey(value);
int
hash = hash(key.hashCode());
int
i = indexFor(hash, table.length);
for
(Entry<K,V> e = table[i]; e !=
null
; e = e.next) {
Object k;
if
(e.hash == hash &&((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(
this
);
return
oldValue; }
}
modCount++;
addEntry(hash, key, value, i);
return
null
;
}
|
Look at the source code of the add method of ArrayList again
1
2
3
4
5
|
public
boolean
add(E e) {
ensureCapacity(size +
1
);
// Increments modCount!!
elementData[size++] = e;
return
true
;
}
|
Look at the append source of StringBuffer, he is modified with synchronized
1
2
3
4
5
|
public
synchronized
StringBuffer append(String str) {
super
.append(str);
return
this
;
}
|
Finally, there is the setProperty method of Properties, which is modified by synchronized
1
2
3
4
5
|
public
synchronized
Object setProperty(String key, String value) {
return
put(key, value);
}
|
From this, you can determine who is thread-safe.