Search code examples
javamultithreadingsynchronizedvolatile

Garbage collection and synchronized visibility


I have read about marking an object as volatile doesn't guarantee visibility of it's members ( I'm not saying about thread safety just memory visibility , quoting :

only the object reference will be considered to be volatile by the JVM and not the object data itself which will reside on the heap

my questions :

  1. The synchronize will ensure the visibility of the members (on the same lock object) in case they have been edited. Is that because the happens-before at the end (release) of the lock which makes the actions visible to the other thread?
  2. In case of using volatile on the object, and the object reference change. what happens if the old reference is cached in one thread CPU cache? Will the GC keep it alive?

Sample code:

class Test{
  volatile Data data;

}

Class Data{
 int x;
 int y;
}


data= new Data(); // happens-before relationship only on creation

 //writer
 Thread writerThread = new Thread(() -> {
    data.setX(a);
    data.setY(b);
   });


 //reader
 Thread readerThread = new Thread(() -> {

  // read here is not guaranteed visibility, x,y not volatile
   int x = data.getX(); 
   int y = data.getY();          
  });

Solution

    1. Yes, happens-before relationship will gurantees that. While volatile keyword also builds happens-before relationship between the write thread and the read thread.

    Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable.

    1. The java language specification does not mention it, or any specific mechanism about how to implement volatile. So I guess it depends on the specific JVM.