For the following simplified class:
public class MutableInteger {
private int value;
public MutableInteger(int initial) {
synchronized(this) { // is this necessary for memory visibility?
this.value = initial;
}
}
public synchronized int get() {
return this.value;
}
public synchronized void increment() {
this.value++;
}
...
}
I guess the general question is for mutable variables guarded by synchronization is it necessary to synchronize when setting the initial value in the constructor?
You're right, without the synchronized
block in the constructor there is no visibility guarantee for non-final fields, as can be seen in this example.
However in practice I would rather use volatile
fields or the Atomic*
classes in situations like this.
Update: It is also important to mention here that in order for your program to be correctly synchronized
(as defined by the JLS), you will need to publish the reference to your object in a safe manner. The cited example doesn't do that, hence why you may see the wrong value in non-final fields. But if you publish the object reference correctly (i.e. by assigning it to a final
field of another object, or by creating it before calling Thread.start()
), it is guaranteed that your object will be seen at least as up-to-date as the time of publishing, therefore making the synchronized
block in the constructor unnecessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With