Search code examples
javasynchronizationvolatile

Java use synchronized and volatile when manipulating multiple properties and locking on a lock object


I need to manipulate multiple properties in Java while keeping them in sync.

Is this code correct (from my understanding this is):

class X {
    private final Object lockObject = new Object();
    private int a;
    private boolean b;
    private Y y;

    public void doStuff(int i) {
          synchronized (lockObject) {
                a = i;
                b = a == 8;
                y.someMethod(b);
                y = new Y(a, y);
          }
    }
}

Does this synchronized block ensure updates to all properties or just the locked property are written (in which case it would not really make sense to lock on a final object with no state)?

Or do I need to use volatile in order to ensure memory visibility updates on all threads:

class X {
    private final Object lockObject = new Object();
    private volatile int a;
    private volatile boolean b;
    private volatile Y y;

    public void doStuff(int i) {
          synchronized (lockObject) {
                a = i;
                b = a == 8;
                y.someMethod(b);
                y = new Y(a, y);
          }
    }
}

I am actually 99% sure the first one is correct but not a 100%, thanks for answers.


Solution

  • the first.

    But, only in interactions between other threads that also lock on this lock object. In other words, if 10 threads all call doStuff simultaneously:

    • Those 10 threads each run the code there in some undefined order.
    • Each of the 10 executions sees the updates of the previous execution, and will run its execution as an atomic unit (i.e. the a == 8 check will see its own a = i, guaranteed, as the state of a.

    There is no need to also declare those fields volatile.