java.util.Timer計時器有管理任務延遲執行("如1000ms後執行任務")以及週期性執行("如每500ms執行一次該任務")。java
可是,Timer存在一些缺陷:ide
1,Timer對調度的支持是基於絕對時間,而不是相對時間的,由此任務對系統時鐘的改變是敏感的;ScheduledThreadExecutor只支持相對時間。 oop
2,若是TimerTask拋出未檢查的異常,Timer將會產生沒法預料的行爲。Timer線程並不捕獲異常,因此 TimerTask拋出的未檢查的異常會終止timer線程。此時,已經被安排但還沒有執行的TimerTask永遠不會再執行了,新的任務也不能被調度了。 測試
測試代碼:spa
public class ScheduledExecutorTest { public static void main(String[] args) throws Exception { final ScheduledExecutorTest test = new ScheduledExecutorTest(); // test.lanuchTimer(); // Thread.sleep(1000*5);//5秒鐘以後添加新任務 // test.addOneTask(); test.lanuchTimer2(); Thread.sleep(1000 * 5);// 5秒鐘以後添加一個新任務 test.addOneTask2(); } private final Timer timer = new Timer(); // 啓動計時器 public void lanuchTimer2() { timer.schedule(new TimerTask() { @Override public void run() { throw new RuntimeException(); } }, 1000 * 3, 500); } // 向計時器添加一個任務 public void addOneTask2() { timer.schedule(new TimerTask() { @Override public void run() { System.out.println("hello world"); } }, 1000 * 1, 1000 * 5); } // public static void main(String[] args) throws Exception { // TimerTest test = new TimerTest(); // test.lanuchTimer(); // Thread.sleep(1000*5);//5秒鐘以後添加一個新任務 // test.addOneTask(); // } }
測試代碼結果:
線程
Exception in thread "Timer-0" java.lang.RuntimeException at com.technology.test.ScheduledExecutorTest$3.run(ScheduledExecutorTest.java:78) at java.util.TimerThread.mainLoop(Unknown Source) at java.util.TimerThread.run(Unknown Source) Exception in thread "main" java.lang.IllegalStateException: Timer already cancelled. at java.util.Timer.sched(Unknown Source) at java.util.Timer.schedule(Unknown Source) at com.technology.test.ScheduledExecutorTest.addOneTask2(ScheduledExecutorTest.java:85) at com.technology.test.ScheduledExecutorTest.main(ScheduledExecutorTest.java:68)
那麼若是使用ScheduledExecutorService呢?日誌
測試代碼以下:code
public class ScheduledExecutorTest { // 線程池能按時間計劃來執行任務,容許用戶設定計劃執行任務的時間,int類型的參數是設定 // 線程池中線程的最小數目。當任務較多時,線程池可能會自動建立更多的工做線程來執行任務 public ScheduledExecutorService scheduExec = Executors .newScheduledThreadPool(1); // 啓動計時器 public void lanuchTimer() { final Runnable task = new Runnable() { @Override public void run() { throw new RuntimeException(); } }; scheduExec.scheduleWithFixedDelay(task, 1000 * 5, 1000 * 10, TimeUnit.MILLISECONDS); } // 添加新任務 public void addOneTask() { final Runnable task = new Runnable() { @Override public void run() { System.out.println("welcome to china"); } }; scheduExec.scheduleWithFixedDelay(task, 1000 * 1, 1000, TimeUnit.MILLISECONDS); } public static void main(String[] args) throws Exception { final ScheduledExecutorTest test = new ScheduledExecutorTest(); // test.lanuchTimer(); // Thread.sleep(1000*5);//5秒鐘以後添加新任務 // test.addOneTask(); test.lanuchTimer(); Thread.sleep(1000 * 5);// 5秒鐘以後添加一個新任務 test.addOneTask(); } }輸入日誌信息爲:
welcome to china welcome to china welcome to china
程序能正確的輸出。it