Timer的缺陷(四)

先定義一個TimerTask類

package lxd.timer.demo;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimerTask;

public class MyTimerTask2 extends TimerTask {
    private String name;

    private long costTime;

    public MyTimerTask2(String name, long costTime) {
        this.name = name;
        this.costTime = costTime;
    }


    @Override
    public void run() {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(name + "'s current exec time is: " 
                + sf.format(calendar.getTime()));
        try {
            Thread.sleep(costTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        calendar = Calendar.getInstance();
        System.out.println(name + "'s finish time is: " 
                + sf.format(calendar.getTime()));
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getCostTime() {
        return costTime;
    }

    public void setCostTime(long costTime) {
        this.costTime = costTime;
    }

}

管理併發任務的缺陷

  • Timer有且僅有一個線程去執行定時任務,如果存在多個任務,且任務執行時間過長,會導致執行效果與預期不符。

測試demo:

package lxd.timer.demo;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;

/**
 * 
 * Timer的缺陷demo
 * 
 * <pre>
 * Timer的缺陷demo,不支持併發
 * </pre>
 * 
 * @author 李曉東
 * 
 * 2017.05.28
 * 
 * @since 1.0
 *
 */
public class MyTimer2 {

    public static void main(String[] args) {
        Timer timer = new Timer();
        MyTimerTask2 task1 = new MyTimerTask2("No.1", 2000);
        MyTimerTask2 task2 = new MyTimerTask2("No.2", 2000);

        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("current time is: " + sf.format(calendar.getTime()));
//      timer.schedule(task1, calendar.getTime());
//      timer.schedule(task2, calendar.getTime());
        timer.scheduleAtFixedRate(task1, calendar.getTime(), 2000);
        timer.scheduleAtFixedRate(task2, calendar.getTime(), 2000);
    }

}

測試結果:

current time is: 2017-05-28 15:58:07
No.1's current exec time is: 2017-05-28 15:58:07
No.1's finish time is: 2017-05-28 15:58:09
No.2's current exec time is: 2017-05-28 15:58:09
No.2's finish time is: 2017-05-28 15:58:11
No.2's current exec time is: 2017-05-28 15:58:11
No.2's finish time is: 2017-05-28 15:58:13
No.1's current exec time is: 2017-05-28 15:58:13
No.1's finish time is: 2017-05-28 15:58:15
No.1's current exec time is: 2017-05-28 15:58:15

以上schedule和scheduleAtFixedRate的效果是一樣的,Timer不支持併發。

當任務拋出異常時的缺陷

  • 如果TimerTask拋出RuntimeException,Timer會停止所有任務的運行。

測試demo,在MyTimerTask2的run方法中加上一句話:

@Override
public void run() {
    Calendar calendar = Calendar.getInstance();
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(name + "'s current exec time is: " 
            + sf.format(calendar.getTime()));
    try {
        Thread.sleep(costTime);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    calendar = Calendar.getInstance();
    System.out.println(name + "'s finish time is: " 
            + sf.format(calendar.getTime()));
    //加上測試運行時異常
    throw new RuntimeException();
}

MyTimer2不變,測試結果:

current time is: 2017-05-28 16:05:35
No.1's current exec time is: 2017-05-28 16:05:35
No.1's finish time is: 2017-05-28 16:05:37
Exception in thread "Timer-0" java.lang.RuntimeException
    at lxd.timer.demo.MyTimerTask2.run(MyTimerTask2.java:32)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)

Timer的使用禁區

  • 對時效性要求較高的多任務併發作業

- 對複雜任務的調度

這個時候需要使用Quartz了!

發佈了110 篇原創文章 · 獲贊 19 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章