gpt4 book ai didi

java - 了解不安全的发布

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:15:06 28 4
gpt4 key购买 nike

在 JCIP 16.2 B.Goetz 中提到

If you do not ensure that publishing the shared reference happens-before another thread loads that shared reference, then the write of the reference to the new object can be reordered (from the perspective of the thread consumign the object) with writes to its fields.

所以我猜想这意味着即使发布具有同步功能的 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();
}
}
}

现在我们在写入 oh 和从方法 get() 返回 oh 之间有happens-before .它保证任何调用者线程观察到 oh 的最新值。

但是,在构造期间写入oh字段(private int aprivate Object o)不是happens-before 连接到 oh。 JMM 不保证这一点。如果我错了,请向 JMM 提供证明引用。因此,即使是这样的发布,读取 oh 的线程也可能会观察到一个部分构造的对象。

那么,他说我在报价单中提供是什么意思?你能澄清一下吗?

最佳答案

如果您只按照上述方法读取或写入oh,则get() 获取的锁将确保您看到锁释放前的所有操作在 SharedObjectHolder 的构造函数中——包括对 oh 字段的任何写入。您所依赖的先行边与写入 oh 无关,而与写入(包括写入 oh 的字段)之前发生的一切无关释放锁,这发生在获取该锁之前,这发生在读取之前。

如果您有一个线程将 get() 重新排序为在构造函数之前发生,

有可能看到部分构造的 oh并且写入 oh 发生在它们之前。这就是需要安全发布 SharedObjectHolder 实例的原因。

(也就是说,如果您可以安全地发布 SharedObjectHolder,我不明白您为什么不能安全地发布原始的 oh 引用。)

关于java - 了解不安全的发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36997173/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com