垃圾收集和同步可见性

时间:2018-12-15 11:10:15

标签: java multithreading synchronized volatile

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

  

JVM仅将对象引用视为易失性,而不是将驻留在堆上的对象数据本身

我的问题:

  1. 如果成员已被编辑,则同步将确保成员(在同一锁定对象上)的可见性。是因为在锁的末端(释放)之前发生,该操作使其他线程可以看到这些操作吗?
  2. 在对象上使用易失性的情况下,对象引用也会更改。如果将旧的引用缓存在一个线程的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 个答案:

答案 0 :(得分:0)

  1. 是的,happens-before关系将确保这一点。尽管volatile关键字还在写线程和读线程之间建立了happens-before关系。
  

使用易失性变量可降低内存一致性的风险   错误,因为任何对volatile变量的写入都会建立一个   发生于事前的关系,以及随后的相同阅读   变量。

  1. java语言规范没有提及它,也没有提及有关如何实现volatile的任何特定机制。所以我想这取决于特定的JVM。