Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - synchronization on non-final field

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.

like image 945
Bober02 Avatar asked Dec 19 '22 16:12

Bober02


2 Answers

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();
like image 71
Mark Peters Avatar answered Jan 08 '23 09:01

Mark Peters


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.

like image 41
Luiggi Mendoza Avatar answered Jan 08 '23 11:01

Luiggi Mendoza