如何使用AtomicBoolean实现这一目标?

时间:2011-05-12 21:28:23

标签: java

如何确保只调用一次initialize()方法?下面是线程不安全的版本,我想重构使用AtomicBoolean。 我想要的只是initialize()只被调用一次

if (!initialized) 
{
   initialize();
   initialized = true;
}

4 个答案:

答案 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();
        }
    }

}