如何确保只调用一次initialize()方法?下面是线程不安全的版本,我想重构使用AtomicBoolean。 我想要的只是initialize()只被调用一次
if (!initialized)
{
initialize();
initialized = true;
}
答案 0 :(得分:4)
private final AtomicBoolean initialized = new AtomicBoolean(false);
//in some method:
if(!initialized.getAndSet(true))
{
initialize();
}
答案 1 :(得分:4)
原则布尔值将不适合您,因为即使尚未完成初始化,进入代码块的第二个线程也将失效。尝试这个,只有当第一个还没有完成时才会阻塞第二个并行,并且在初始化完成时会非常快:
volatile boolean initialized = false;
private final Object LOCK = new Object();
public void ensureInitialized() {
if( !initialized ) {
synchronized(LOCK) {
if( !initialized ) {
initialize();
initialized = true;
}
}
}
}
这也被称为双重检查锁定ideom,这样就可以了。
答案 2 :(得分:0)
实际上,您不需要具有以下代码的原子布尔值:
public class YourClass() {
volatile boolean initialized = false;
public void ensureInitialized() {
if ( initialized ) return;
synchronized(this) {
if (!initialized) {
initialize();
initialized = true;
}
}
}
// The code of this method could be moved
// into the synchronized statement above
public void initialize() { ... };
}
由于初始化代码只会被调用一次,因此使用AtomicBoolean没有任何实际好处。
同步'this'可能需要更多时间,但创建AtomicBoolean也是如此。这两个操作只发生一次。
总体而言,此解决方案使用的内存较少。
编辑:更新了解决方案
答案 3 :(得分:0)
class SomeClass {
private AtomicBoolean isInitialized = new AtomicBoolean(false);
private void someMethod() {
if (!isInitialized.compareAndSet(false, true)) {
initialize();
}
}
}