稍微修改一下维基百科中的规范中断双检查锁:
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
// Create new Helper instance and store reference on
// stack so other threads can't see it.
Helper myHelper = new Helper();
// Atomically publish this instance.
atomicSet(helper, myHelper);
}
}
}
return helper;
}
}简单地让新创建的Helper实例原子的发布使这个双重检查的锁定习语安全吗?假设底层原子操作库正常工作吗?我意识到在Java中,人们可以只使用volatile,但是即使这个例子是用伪Java,这应该是一个语言不可知论的问题。
还请参见:
发布于 2009-02-24 19:21:51
它完全取决于平台/语言的确切内存模型。
我的经验法则是:不要这么做。在本例中,无锁(或减少锁)编程很难,除非您是一个线程忍者,否则不应该尝试。你甚至应该考虑它时,你已经得到了分析证明,你真的需要它,在这种情况下,你得到了绝对最好的,最近的书,为这个特定的平台,看看它是否可以帮助你。
发布于 2009-02-24 19:14:26
我认为,如果不完全脱离代码,就无法以语言不可知论的方式回答这个问题。这完全取决于synchronized和atomicSet在伪代码中的工作方式。
发布于 2009-02-24 19:23:08
答案取决于语言--归根结底是atomicSet()提供的保证。
如果myHelper的构造可以在atomicSet()之后展开,那么变量如何分配到共享状态并不重要。
即
// Create new Helper instance and store reference on
// stack so other threads can't see it.
Helper myHelper = new Helper(); // ALLOCATE MEMORY HERE BUT DON'T INITIALISE
// Atomically publish this instance.
atomicSet(helper, myHelper); // ATOMICALLY POINT UNINITIALISED MEMORY from helper
// other thread gets run at this time and tries to use helper object
// AT THE PROGRAMS LEISURE INITIALISE Helper object.如果语言允许这样做,则重复检查将无法工作。
https://stackoverflow.com/questions/583123
复制相似问题