我有一些代码需要进行一次性初始化。但是这些代码没有明确的生命周期,因此在我的初始化完成之前,我的逻辑可以被多个线程潜在地调用。因此,我希望基本上确保我的逻辑代码“等待”直到初始化完成。
这是我的第一次尝试。
public class MyClass {
private static final AtomicBoolean initialised = new AtomicBoolean(false);
public void initialise() {
synchronized(initialised) {
initStuff();
initialised.getAndSet(true);
initialised.notifyAll();
}
}
public void doStuff() {
synchronized(initialised) {
if (!initialised.get()) {
try {
initialised.wait();
} catch (InterruptedException ex) {
throw new RuntimeException("Uh oh!", ex);
}
}
}
doOtherStuff();
}
}
我想确认一下这个代码是否能够做到我想要的效果——阻塞doStuff直到initialised为true,并且我没有忽略任何竞争条件,导致doStuff可能会被Object.wait()卡住而永远无法执行。
编辑:
我无法控制线程。而且我想要能够控制所有初始化完成的时间,这就是为什么doStuff()不能调用initialise()的原因。
我使用了AtomicBoolean,因为它既可以作为值持有者,又可以作为一个我可以同步的对象。我也可以简单地使用“public static final Object lock = new Object();”和一个简单的布尔标志。AtomicBoolean恰好给了我这两个功能。布尔值是不可修改的。
CountDownLatch正是我所需要的东西。我还考虑过使用0个许可的Sempahore。但CountDownLatch对于这个任务来说是完美的。