【发布时间】:2016-05-03 06:30:12
【问题描述】:
在 JCIP 16.2 B.Goetz 中提到
如果您不确保发布共享参考 发生-在另一个线程加载该共享引用之前,然后 对新对象的引用的写入可以重新排序(从 线程消耗对象的视角)并写入其 字段。
所以我猜这意味着即使发布带有同步的 NotThreadSafe 对象就足够了。考虑以下共享对象
public ObjectHolder{
private int a = 1;
private Object o = new Object();
//Not synchronizaed GET, SET
}
//Assume that the SharedObjectHolder published
//with enough level of synchronization
public class SharedObjectHolder{
private ObjectHolder oh;
private final Lock lock = new ReentrantLock();
public SharedObjectHolder(){
lock.lock();
try{
oh = new ObjectHolder();
} finally {
lock.unlock();
}
}
public ObjectHolder get(){
lock.lock();
try{
return oh;
} finally {
lock.unlock();
}
}
}
现在我们 happens-before 在写入 oh 和从方法 get() 返回 oh 之间。它保证任何调用者线程都观察到oh 的最新值。
但是,在构造过程中写入oh 字段(private int a,private Object o)不是happens-before,而是写入oh。 JMM 不保证这一点。如果我错了,请提供 JMM 的证明参考。因此,即使有这样的发布,读取oh 的线程也可能会观察到一个部分构造的对象。
那么,他说我在报价中提供了是什么意思?你能澄清一下吗?
【问题讨论】:
-
为什么你需要一个锁在构造函数中(或者实际上是
get())?只需将oh设为final,然后赋值发生在构造函数返回之前。 -
那么你认为锁会保证在构造函数完成之前无法执行#get方法吗?好笑
-
@AdamSkywalker 我不能只做最后...
标签: java multithreading shared-memory