垃圾收集和同步可见性

Garbage collection and synchronized visibility

我读过有关将对象标记为 volatile 的内容并不能保证其成员的可见性(我不是在说线程安全只是内存可见性,引用:

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

我的问题:

  1. 同步将确保成员(在同一个锁对象上)的可见性,以防它们被编辑。那是因为结束(释放)之前发生的事情使得其他线程可以看到操作吗?
  2. 在对象上使用 volatile 的情况下,对象引用发生变化。如果旧引用缓存在一个线程 CPU 缓存中会怎样? GC 会让它存活吗?

示例代码:

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();          
  });
  1. 是的,happens-before 关系将保证这一点。而 volatile 关键字还在写入线程和读取线程之间建立 happens-before 关系。

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. java 语言规范没有提到它,也没有提到任何关于如何实现 volatile 的具体机制。所以我猜这取决于具体的JVM。