2012-08-03 53 views
1

我有一個非常簡單的Runnable,我希望每30秒執行一次 - 請記住,這僅僅是這個問題的簡單示例,而不是實際的要點在現實中使用這個。在Java中調度循環任務而不停止未經檢查的異常

@Override 
public void run() { 
    System.out.println("Throwing an unchecked exception on purpose..."); 
    int abc = 123 - 123; 
    int def = 123/abc; 
} 

我用定時器和TimerTask,但遇到了一個問題:每當TimerTask的提出了一個未經檢查的異常,該任務的任何後續執行將被取消;因此上面的任務實際上只會運行一次,因爲它會通過0 Exception拋出未經檢查的除法。

據我所知,ScheduledThreadPoolExecutor具有完全相同的「功能」,至少根據官方的Java API文檔「如果任務的任何執行遇到異常,後續執行被抑制」。

在Java中是否有任何標準方法使Timer或ScheduledThreadPoolExecutor在引發未檢查異常時不抑制後續執行?

非常感謝。

+0

您需要使用try/catch語句並捕獲異常。 – 2012-08-03 16:41:22

+0

@ DMB3我可能會很慢,但爲什麼捕捉這個RuntimeException將是一件壞事? – Eugene 2012-08-03 16:51:05

+0

特定的Runnable中的代碼可能在項目之外實現,因此我們無法訪問代碼以在該處捕獲異常。 Jon Skeet提出的包裝解決方案顯然完成了這一點。 – DMB3 2012-08-03 17:04:11

回答

4

Java中是否有任何標準方法使Timer或ScheduledThreadPoolExecutor在引發未檢查異常時不抑制後續執行?

那麼有一個很簡單方式 - 創建一個ExceptionSuppressingRunnable它包裝另一個問題:

public final class ExceptionSuppressingRunnable implements Runnable 
{ 
    private final Runnable original; 

    public ExceptionSuppressingRunnable(Runnable runnable) 
    { 
     // TODO: Null validation 
    } 

    public void run() 
    { 
     try 
     { 
      original.run(); 
     } 
     catch (RuntimeException e) 
     { 
      // TODO: Logging 
     } 
    } 
} 

注意這個故意不趕Error(或Throwable的任何其他非異常的子類) 。你可能Exception而不是RuntimeException - 它只會在奇怪的情況下,在代碼拋出檢查的異常而未聲明它(由於字節碼重寫,版本差異或其他)而產生差異。我認爲它可能更清晰地抓住RuntimeException

+0

是的,顯然有一個嘗試/抓住周圍的整個代碼有點解決它,但我更多的思考無需實際做到這一點。但顯然這很有效。 – DMB3 2012-08-03 16:56:20

+0

@ DMB3:這將行爲置於*單獨的地方(非常簡單),而不依賴任何特定的計時器等。它將「抑制和記錄異常」的注意力從「定期運行特定任務」中分離出來。 – 2012-08-03 16:58:49

+0

是的。這確實奏效,我猜想找到更多晦澀的替代品沒有意義。謝謝。 – DMB3 2012-08-03 17:04:47