定時任務用Timer實現有可能出現異常,因為它是基於絕對時間而不是相對時間進行調度的。當環境的系統時間被修改后,原來的定時任務可能就不跑了。另外需要注意一點,捕獲並處理定時任務的異常。如果在TimerTask里拋出了異常,那么Timer認為定時任務被取消並終止執行線程。舉例:
package com.wulinfeng.concurrent; import java.util.Timer; import java.util.TimerTask; public class OutOfTime { public static void main(String[] args) throws InterruptedException { Timer timer = new Timer(); // 設置一個一次性的定時任務,1秒后執行 timer.schedule(new PrintTask(), 1000); // 休眠一秒 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 設置一個一次性任務,間隔1秒執行 timer.schedule(new ThrowTask(), 1000); // 休眠一秒 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 再設置一個周期性任務,可是不會再來了 timer.schedule(new PrintTask(), 1000, 1000); } static class PrintTask extends TimerTask { @Override public void run() { System.out.println("I'm coming..."); } } static class ThrowTask extends TimerTask { @Override public void run() { throw new RuntimeException(); } } }
運行結果:
I'm coming... Exception in thread "Timer-0" java.lang.RuntimeException at com.wulinfeng.concurrent.OutOfTime$ThrowTask.run(OutOfTime.java:50) at java.util.TimerThread.mainLoop(Timer.java:555) at java.util.TimerThread.run(Timer.java:505) Exception in thread "main" java.lang.IllegalStateException: Timer already cancelled. at java.util.Timer.sched(Timer.java:397) at java.util.Timer.schedule(Timer.java:248) at com.wulinfeng.concurrent.OutOfTime.main(OutOfTime.java:34)
如果注掉這一行,那么定時任務還是會一直跑下去的
timer.schedule(new ThrowTask(), 1000);