歸結爲一個線程通過某種服務提交作業。作業在一些TPExecutor中執行。之後,此服務會在特定條件下檢查結果並在原始線程中拋出異常(作業超過最大重試次數等)。下面的代碼片段大致說明了此方案中的遺留代碼:如何使用CountDownLatch正確同步/鎖定
import java.util.concurrent.CountDownLatch;
public class IncorrectLockingExample {
private static class Request {
private final CountDownLatch latch = new CountDownLatch(1);
private Throwable throwable;
public void await() {
try {
latch.await();
} catch (InterruptedException ignoredForDemoPurposes) {
}
}
public void countDown() {
latch.countDown();
}
public Throwable getThrowable() {
return throwable;
}
public void setThrowable(Throwable throwable) {
this.throwable = throwable;
}
}
private static final Request wrapper = new Request();
public static void main(String[] args) throws InterruptedException {
final Thread blockedThread = new Thread() {
public void run() {
wrapper.await();
synchronized (wrapper) {
if (wrapper.getThrowable() != null)
throw new RuntimeException(wrapper.getThrowable());
}
}
};
final Thread workingThread = new Thread() {
public void run() {
wrapper.setThrowable(new RuntimeException());
wrapper.countDown();
}
};
blockedThread.start();
workingThread.start();
blockedThread.join();
workingThread.join();
}
}
有時,(在我的箱子不可複製的,但發生在16核服務器箱)異常沒有得到報告給原來的線程。我認爲這是因爲發生 - 之前不是強迫的(例如'countDown'發生在'setThrowable'之前)並且程序繼續工作(但應該失敗)。 我將不勝感激關於如何解決這種情況的任何幫助。 約束條件是:一週內發佈,需要對現有代碼庫的影響最小。
250 KLOC項目在這裏完全是多線程的,工作在16核心等。我們使用像「CountDownLatch」*「lot **」這樣的「高級」多線程工具。我們使用低級別事物的次數,例如* Object *的wait *方法和* Thread *的join *方法? **零**。在我看來,現在在默認API中有足夠多的高級併發功能,您不需要重新創建基於Java idiosynchrasies的任何碎輪。 +1給Peter Lawrey的答案。 – SyntaxT3rr0r 2010-12-04 13:18:36
@ Webinator:OP *在此處使用「高級」CountDownLatch工具來實現其設計目的之一。 – willjcroz 2010-12-04 13:38:38
您確定上面的代碼不符合預期嗎?我認爲沒有理由不糾正之後。 – willjcroz 2010-12-04 13:46:04