垃圾收集和同步可见性
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
我的问题:
- 同步将确保成员(在同一个锁对象上)的可见性,以防它们被编辑。那是因为锁结束(释放)之前发生的事情使得其他线程可以看到操作吗?
- 在对象上使用 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();
});
- 是的,
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.
- java 语言规范没有提到它,也没有提到任何关于如何实现 volatile 的具体机制。所以我猜这取决于具体的JVM。
我读过有关将对象标记为 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
我的问题:
- 同步将确保成员(在同一个锁对象上)的可见性,以防它们被编辑。那是因为锁结束(释放)之前发生的事情使得其他线程可以看到操作吗?
- 在对象上使用 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();
});
- 是的,
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.
- java 语言规范没有提到它,也没有提到任何关于如何实现 volatile 的具体机制。所以我猜这取决于具体的JVM。