對於執行週期任務,我看着Timer
和ScheduledThreadPoolExecutor
(通過單個線程),並決定使用後者,因爲在reference for Executors.newSingleThreadScheduledExecutor()
,它說:爲什麼ScheduledExecutorService在拋出異常後不能再次運行任務?
不過請注意,如果這個單一線程終止由於在關機之前的執行過程中出現故障,如果需要執行後續任務,則會取代它。
我的計劃是將此用作防範未監測到的一段代碼中的未捕獲異常,以監控其他操作。我想確認並寫下下面的測試,並立即失敗。看來我在做錯誤的假設,或者對我的測試錯誤?
下面的代碼:
@Test
public void testTimer() {
final AtomicInteger cTries = new AtomicInteger(0);
final AtomicInteger cSuccesses = new AtomicInteger(0);
TimerTask task = new TimerTask() {
@Override
public void run()
{
cTries.incrementAndGet();
if (true) {
throw new RuntimeException();
}
cSuccesses.incrementAndGet();
}
};
/*
Timer t = new Timer();
t.scheduleAtFixedRate(task, 0, 500);
*/
ScheduledExecutorService exe = Executors.newSingleThreadScheduledExecutor();
exe.scheduleAtFixedRate(task, 0, 500, TimeUnit.MILLISECONDS);
synchronized (this) {
try {
wait(3000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
exe.shutdown();
/*
t.purge();
*/
Assert.assertEquals(cSuccesses.get(), 0);
Assert.assertTrue(cTries.get() > 1, String.format("%d is not greater than 1. :(", cTries.get()));
}
我知道,我可以圍繞東西包裹一個(可扔),但我的計劃是以某種方式保護我自己。 –
對於像這樣的框架代碼來說,假設它可以安全地重新啓動失敗的作業會有問題 - 事件發生失敗並出現異常意味着數據可能已經保留在任何狀態,並且可能會重新啓動工作。 –
關於啓動新線程的引用是允許其他作業繼續運行,即使其中一個失敗 –