2010-07-22 70 views
2

有一天,我在我的應用程序中實施了一項重要的服務,無論如何該應該繼續運行。所以我用以下結構:如果任務拋出RuntimeException/Error,ScheduledExecutorService.scheduleAt *方法應該重新計劃任務嗎?

ScheduledExecutorService ses = 
Executors.newSingleThreadScheduledExecutor(); 

//If the thread dies, another will take over 
ses.scheduleAtFixedRate(importantPeriodicTask, 1, 1, TimeUnit.NANOSECONDS); 

...才發現,當importantPeriodicTask acutually拋出RuntimeException或錯誤,ScheduledExecutorService將停止執行這項任務(它們將不再安排)。

這當然正是javadoc中說:

如果 遇到異常任務的任何執行,後續 執行被抑制。

對我很恥辱,但我不明白爲什麼作者實施這樣的ScheduledExecutorService

當然,RuntimeException或Error通常不會被捕獲,特別是Error。但實際上,特別是在RuntimeException的情況下,事實是它們在生產部署中非常常見,我認爲在特定操作失敗的情況下,應用本身不應該因爲這種孤立的錯誤而失敗。

確實,抑制一個週期性任務不會影響其他類型的週期性任務。但考慮到大多數週期性任務的性質,這些任務不應該被看作是「服務」,而不是孤立的任務?

換句話說,不僅importantPeriodicTask的一個實例失敗,並且任務本身會繼續被重新計劃?

+0

這是事情是這樣的,我不知道你是什麼樣的答案尋找。如果你不喜歡它,你需要將任務包裝到捕捉異常的東西中。 – skaffman 2010-07-22 13:00:03

+1

@skaffman:我確實懂得如何獲得想要的(我的意思是我想要的)行爲,但我很好奇別人的想法。 – 2010-07-22 13:03:46

回答

3

在我看來,目前的行爲是合理的。 RuntimeExceptions通常指的是錯誤。他們實際上可以發生在任務代碼的任何地方。例如,如果任務是有狀態的,則可能會使其狀態不一致,並且隨後的執行會產生意外的行爲。總的來說,我不喜歡試圖從自己的錯誤中恢復的代碼,但這是我的看法。

如果你想改變ScheduledExecutorService的行爲,看看下面的通用的解決方案:

http://www.javaspecialists.eu/archive/Issue154.html

+0

我普遍認同,但是再一次,編寫錯誤也不難免費軟件? – 2010-07-22 13:05:23