Are object parameters of synchronized block guranteed visibilty Synchronized Java

82 Views Asked by At

I cannot find an answer for the following case:

  public class Example {
    int a=0;

    public  synchronized void method(Object x){
        a++;
        x.value=x.value+1;
    }
}

I know that happens-before relation is established for the same object lock , so everything should be written to the memory (but not sure if everything here include changes to x ) ,

my question : are the changes to the object x guranteed to be visible for other thread if they are using the same lock ? ( lock is on example object , but not on x itself)

1

There are 1 best solutions below

10
Stephen C On

Are the changes to the object x guaranteed to be visible for other thread if they are using the same lock?

Yes, but this may not be useful.

First I need to turn your example code into something that compiles, and can be used to illustrate your question.

public class Example {
    int a = 0;

    public  synchronized void method(X x){
        a++;
        x.value = x.value+1;
    }
}

public class X {
    int value;
}   

The scenario is then as follows:

  1. An instance of Example and Shared are created and passed to two threads A and B.

  2. Thread A calls example.method(x) with the common instances.

  3. Some time later Thread B calls example.method(x) with the common instances.

There will be a happens before relation between thread A releasing the mutex on the Example instance and thread B acquiring this. When we combine this with happens before relations for the sequential execution of the body of method, we will get a guarantee that

  • EITHER Thread B will see the updated value of the value variable written by A
  • OR it will see another value written after that.

Furthermore, if any code writes to x.value outside of a method call, or using a different Example instance as a lock, then all bets are off. And there are no guarantees about what another thread would see if it read x.value directly.


In summary, there is some guaranteed behavior, but because of the caveats surrounding the guarantee, it is difficult to exploit them safely. It would be better to do one of the following:

  • lock directly on the X instances; e.g. via a synchronized increment method on X), or
  • hide the X instances so that they are only operated on by (for example) synchronized methods of Example.