this class can be used in multi thread because it is thread-safe.
public class Hello {
private int value = 0;
public synchronized int get() {
return value;
}
public synchronized void set(int value) {
this.value = value;
}
}
i know that the reason that we must use synchronized when get() ,besides set() is memory visibility.
and java volatile keyword can be used for memory visibility.
so then.. this class is also thread-safe??
public class Hello {
private volatile int value = 0;
public int get() {
return value;
}
public synchronized void set(int value) {
this.value = value;
}
}
In your specific example, you don't need that extra synchronized. Given that you have already mentioned memory visibility (aka happens-before), I won't go deeper to explain this.
However, it does not apply generally. There are several assumptions in your example making it enough to simply use
volatileType of
valueAlthough you are simply doing a simple retrieval/assignment ofvalue, it is not always guaranteed to be atomic for all data type. Iirc, Java only guarantee that such operation is atomic forintand types smaller thatint. Which means, for example, ifvalueis of typelong, even you have declared it withvolatile, you may still corruptvaluewith your above exampleOperations on
valueOk, let's assume it is an
int. In your example, you are simply getting and assigning anintfor which the operation is atomic, hence simply usingvolatileis enough. However if you have another method doing something likevalue++, usingvolatileis not sufficient. In such case, you may either consider usingAtomic*or usesynchronizedUpdate: I later found that JLS https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7 mentioned that using volatile would enforce atomic read/write on double/long. So my original point 1 was actually wrong