2012-07-12 179 views
2

我有一個Java類,它的主要方法啓動TimerTask,擴展TimerTask類是一個內部類(類myTimer擴展TimerTask)。在myTimer拋出一個異常,它的run方法,在main方法我試圖捕獲異常這樣的:無法捕獲TimerTask線程異常

try { 
    timer.schedule(new myTimer(arg1, arg2), 0, RETRY_PERIOD); 
} catch (Exception e) { 
    System.out.println("Exception caught"); 
} 

但是,這並不工作,它從來沒有捕獲該異常,myTimer線程拋出。任何想法如何做到這一點?

回答

2

您的情況有點棘手,我不確定您的代碼段中會發生什麼。你期望主線程阻塞,直到計時器線程拋出異常嗎?因爲那不會發生。 try-catch唯一能做的就是捕獲在調用schedule時發生的異常,而不是定期在線程執行的代碼中。

無論如何這是沒有意義的。由於定時器線程可以與主線程並行拋出異常,因此您需要定期凍結主線程以檢查異常或永久凍結它,直到定時器結束。

後一種情況可以用ScheduledThreadPoolExecutor容易地完成:

ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1); 
ScheduledFuture f = exec.scheduleWithFixedDelay(new Task(arg1, arg2), 0, 
            RETRY_PERIOD, TimeUnit.MILLISECONDS); 

... 
try { 
    f.get(); // wait for task to finish 
} catch(ExecutionException ex) { 
    System.out.println("Exception caught"); 
} 

其中Task是實現Runnable的類。

當然,這將阻塞主線程,直到任務返回或引發異常(可能永遠不會發生)。或者,您可以使用定時獲取來定期檢查異常情況。

+0

現在當我運行它時,它會捕獲異常,但程序不會在此之後終止 – comatose 2012-07-13 08:31:23

+0

@comatose:如果要立即退出方法,可以在catch塊的末尾放置一個'return' 。 – Tudor 2012-07-13 08:46:54

2

Timer將從該添加它的主要方法父類將無法趕上拋出異常的線程來執行在不同線程TimerTask.run()方法。

可能的解決方案是防止異常傳播出run()方法,並通過某種查詢方法向父級提供任何有用的信息。在查詢結果之前,父母需要等待run()方法完成。