Timer 的缺陷


  java.util.Timer計時器有管理任務延遲執行("如1000ms后執行任務")以及周期性執行("如每500ms執行一次該任務")。但是,Timer存在一些缺陷,因此你應該考慮使用ScheduledThreadPoolExecutor作為代替品,Timer對調度的支持是基於絕對時間,而不是相對時間的,由此任務對系統時鍾的改變是敏感的;ScheduledThreadExecutor只支持相對時間。

    Timer的另一個問題在於,如果TimerTask拋出未檢查的異常,Timer將會產生無法預料的行為。Timer線程並不捕獲異常,所以TimerTask拋出的未檢查的異常會終止timer線程。這種情況下,Timer也不會再重新恢復線程的執行了;它錯誤的認為整個Timer都被取消了。此時,已經被安排但尚未執行的TimerTask永遠不會再執行了,新的任務也不能被調度了。

 

public class OutOfTime {
    public static void main(String[] args) throws Exception {
        Timer timer = new Timer();
        timer.schedule(new ThrowTask(), 1);
        SECONDS.sleep(1);
        timer.schedule(new ThrowTask(), 1);
        SECONDS.sleep(5);
    }

    static class ThrowTask extends TimerTask {
        public void run() {
            /*try {
                 Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }*/
            throw new RuntimeException();
        }
    }
}

執行結果

Exception in thread "Timer-0" java.lang.RuntimeException
    at net.jcip.examples.OutOfTime$ThrowTask.run(OutOfTime.java:31)
    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:193)
    at net.jcip.examples.OutOfTime.main(OutOfTime.java:19)

 

Timer單線程執行任務,任務有可能丟失或執行時間不准確。

 

  Timer執行任務時只是創建了單個線程。如果一個時間任務執行的時間比較長,那么其他任務執行時間的准確性就會受影響。比如每隔1秒執行一次任務,中間有個長任務執行時間超過5秒,那么在上一個任務執行完成時,會快速執行4次或者丟失任務。

public class OutOfTime {
    public static void main(String[] args) throws Exception {
        Timer timer = new Timer();
        timer.schedule(new ThrowTask(), 1);
        SECONDS.sleep(1);
        timer.schedule(new ThrowTask(), 1);
        SECONDS.sleep(5);
    }

    static class ThrowTask extends TimerTask {
        public void run() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            throw new RuntimeException();
        }
    }
}

執行結果

Exception in thread "Timer-0" java.lang.RuntimeException
    at net.jcip.examples.OutOfTime$ThrowTask.run(OutOfTime.java:31)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM