In the case of synchronizing on a field that can change its reference, as described below:
class A {
Object someObject;
void method(){
synchronized (someObject) {
Object newObject = new Object();
//possibly modify the old ref
if(chackCondition()){
someObject = newObject;
}
}
}
}
I am worried that there might be some weird, low-level compiler optimization I am missing here that might let two threads access the synchronized area concurrently. Any comments would be greatly appreaciated.
You're absolutely right. The moment newObject
is exposed to other threads as the new value of someObject
, those other threads are now using a completely different mutex, and so can be executing the "mutually exclusive" code concurrently.
A common solution is to just provide a different mutex and synchronize on that:
private final Object someObjectMutex = new Object();
There's no optimization here. Two or several threads won't be synchronized at that point if someObject
object reference is different for them. This is the reason why the object should be a final
field. Also, if all threads using different instances of A
must be synchronized at that point, mark the field as static
.
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