Java執行定時任務


一、用java.util.Timer

使用JAVA類Timer可實現簡單的延遲和周期性任務,其中的任務使用java.util.TimerTask表示。任務的執行方式有兩種:

  • 按固定速率執行:即scheduleAtFixedRate的兩個重載方法
Timer timer = new Timer();  
timer. scheduleAtFixedRate(new TimerTask() {  
    @Override  
    public void run() {  
        System.out.println("Timer is running");  
    }  
}, 2000, 5000); 

 

  • 按固定延遲執行:即schedule的4個重載方法
Timer timer = new Timer();  
timer.schedule(new TimerTask() {  
    @Override  
    public void run() {  
        System.out.println("Timer is running");  
    }  
}, 2000);  

 

我們要實現一個定時任務,只需要實現TimerTask的run方法即可。每一個任務都有下一次執行時間nextExecutionTime(毫秒),如果是周期性的任務,那么每次執行都會更新這個時間為下一次的執行時間,當nextExecutionTime小於當前時間時,都會執行它。

Timer的缺陷

1、由於執行任務的線程只有一個,所以如果某個任務的執行時間過長,那么將破壞其他任務的定時精確性。如一個任務每1秒執行一次,而另一個任務執行一次需要5秒,那么如果是固定速率的任務,那么會在5秒這個任務執行完成后連續執行5次,而固定延遲的任務將丟失4次執行。

2、如果執行某個任務過程中拋出了異常,那么執行線程將會終止,導致Timer中的其他任務也不能再執行。

3、Timer使用的是絕對時間,即是某個時間點,所以它執行依賴系統的時間,如果系統時間修改了的話,將導致任務可能不會被執行。

二、使用ScheduledThreadPoolExecutor

由於Timer存在上面說的這些缺陷,在JDK1.5中,我們可以使用ScheduledThreadPoolExecutor來代替它,使用Executors.newScheduledThreadPool工廠方法或使用ScheduledThreadPoolExecutor的構造函數來創建定時任務,它是基於線程池的實現,不會存在Timer存在的上述問題,當線程數量為1時,它相當於Timer。

  ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  
          scheduledThreadPool.schedule(new Runnable() {  
           public void run() {  
            System.out.println("delay 3 seconds");  
           }  
          }, 3, TimeUnit.SECONDS);  
                      
          scheduledThreadPool.scheduleAtFixedRate(()->
            System.out.println("delay 1 seconds, and excute every 3 seconds") 
          , 1, 3, TimeUnit.SECONDS);  

 


免責聲明!

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



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