定時任務執行利器Timer和ScheduledThreadPoolExecutor使用

定時任務是在指定時間執行程序,或週期性執行計劃任務。java

Java中實現定時任務的方法有不少,主要JDK自帶的一些方法以及開源程序如Qurtz。多線程

1.Timer和TimerTask

Timer只是充當了一個執行者的角色,真正的任務邏輯是經過一個叫作TimerTask的抽象類完成的,TimerTask也是java.util包下面的類,
它是一個實現了Runnable接口的抽象類,包含一個抽象方法run( )方法,須要咱們本身去提供具體的業務實現。ide

Timer 的優勢在於簡單易用,但因爲全部任務都是由同一個線程來調度,
所以全部任務都是串行執行的,同一時間只能有一個任務在執行,前一個任務的延遲或異常都將會影響到以後的任務。學習

示例代碼:spa

1.net

2線程

3code

4orm

5繼承

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

public class TimerTest { 

    //被執行的任務必須繼承TimerTask,而且實現run方法

    static class MyTimerTask1 extends TimerTask { 

        public void run() { 

            System.out.println("執行當前線程"+Thread.currentThread().getName()); 

        

    }    

    /**

     * Timer線程不會捕獲異常,因此TimerTask拋出的未檢查的異常會終止timer線程。

     * 若是Timer線程中存在多個計劃任務,其中一個計劃任務拋出未檢查的異常,則會引發整個Timer線程結束,從而致使其餘計劃任務沒法獲得繼續執行。  

     * Timer線程時基於絕對時間,所以計劃任務對系統的時間的改變是敏感的。

     * Timer是單線程,若是某個任務很耗時,可能會影響其餘計劃任務的執行。

     * @param args

     * @throws ParseException

     * @throws InterruptedException

     */

    public static void main(String[] args) throws ParseException, InterruptedException { 

        Timer timer = new Timer(); 

        /**

         * scheduleAtFixedRate方式

         * 設定兩秒後執行任務

         */

        timer.scheduleAtFixedRate(new MyTimerTask1(), 2000,1000);

        /**

         * schedule添加Date參數

         * 設定任務在執行時間執行

         */

//        SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 

//        Date time = dateFormatter.parse("2016/03/28 14:40:00"); 

//        timer.schedule(new MyTimerTask1(), time);

        //啓動MyTimerTask1線程後,主線程休眠五秒鐘,給MyTimerTask1五秒的執行時間

        Thread.sleep(5000);

        //終止Timer線程

        timer.cancel();

        

}

  JDK 5.0之後推薦使用ScheduledThreadPoolExecutor。關於Timer簡單瞭解便可。


2.ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor屬於Executor Framework,
它除了能處理異常外,還能夠以多線程方式執行定時任務。
Timer類是經過單線程來執行全部的TimerTask任務的,若是一個任務的執行過程很是耗時,將會致使其餘任務的時效性出現問題。
而 ScheduledThreadPoolExecutor是基於線程池的多線程執行任務,不會存在這樣的問題。

經過一個實例學習:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

public class ScheduledThreadPoolExecutorTest {

 

    public static void main(String[] args) { 

        //得到實例,而且設置它的容量爲5個 

        ScheduledThreadPoolExecutor sExecutor=new ScheduledThreadPoolExecutor(5);

        MyTask task = new MyTask();

        //隔2秒後開始執行任務,而且在上一次任務開始後隔一秒再執行一次

//      sExecutor.scheduleWithFixedDelay(task, 2, 1, TimeUnit.SECONDS); 

        //隔6秒後執行一次,但只會執行一次

        sExecutor.schedule(task, 6, TimeUnit.SECONDS);

        /**

         * 和Timer相似,也能夠直接在任務的run()方法中調用調度方法中止

         * 這個方法會平滑的關閉調度器,等待全部任務結束

         */

        sExecutor.shutdown();

         

    }

     

    static class MyTask implements Runnable{

 

        @Override

        public void run() {

            System.out.println("當前執行的線程"+Thread.currentThread().getName());

        }

         

    }

}

 

3.使用Qurtz

Qurtz的使用很是簡單,做爲解決方案支持更多的觸發機制。

具體的應用能夠查看官方文檔:http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/

相關文章
相關標籤/搜索