我有一些代碼需要進行一次初始化。但是這段代碼沒有明確的生命週期,所以我的邏輯可能會在我的初始化完成之前被多個線程調用。所以,我想基本確保我的邏輯代碼「等待」,直到初始化完成。啓動時控制競態條件
這是我的第一次切割。
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直到初始化是真實的,那我絕不錯過的競爭條件,其中doStuff可能會被卡住在一個永遠不會到達的Object.wait()上。
編輯:
我無法控制線程。我希望能夠控制什麼時候所有的初始化完成,這就是爲什麼doStuff()不能調用initialise()。
我使用了一個AtomicBoolean,因爲它是一個值持有者和一個可以同步的對象的組合。我本來可以簡單地有一個「公共靜態最終對象鎖=新對象();」和一個簡單的布爾標誌。 AtomicBoolean方便地給了我兩個。布爾值不能被修改。
CountDownLatch正是我所期待的。我也考慮過使用0許可證的Sempahore。但CountDownLatch完美適用於這項任務。
爲什麼不使用靜態初始化器? – 2010-05-20 21:29:14
初始化在哪裏被調用? – luke 2010-05-20 21:30:22
你是否在構造函數中啓動線程來執行初始化工作? – rmarimon 2010-05-20 21:30:39