1. 程式人生 > >Java併發——定時器框架

Java併發——定時器框架

1. 定時器框架

類Timer和TimerTask組成了Timer框架。

Timer是jdk中提供的一個定時器工具,使用的時候會在主執行緒之外起一個單獨的執行緒執行指定的計劃任務,可以指定執行一次或者反覆執行多次。

TimerTask是一個實現了Runnable介面的抽象類,代表一個可以被Timer執行的任務。

import java.util.Timer;
import java.util.TimerTask;

//定時器框架。定時器任務單次執行或規律性的重複執行

//每隔1000毫秒輸出當前時間
public class TimerDemo {

	public static void main(String[] args)
	{
		TimerTask task = new TimerTask()
				{
			         @Override
			         public void run()
			         {
			        	 System.out.println(System.currentTimeMillis());
			         }
				};
		Timer timer = new Timer();
		timer.schedule(task,0, 1000);
	}
}

2.Timer類

Timer適用於大規模併發排程定時任務。在內部,該類使用了一個二進位制的堆表示其定時任務佇列,使得排程定時任務的開銷為O(log n),這裡的n就是併發排程定時任務的數量。

常用函式:

(1)Timer():建立一個新的定時器,其任務執行執行緒是非守護執行緒。

(2)Timer(boolean isDaemon):建立一個新的定時器,其任務執行執行緒可能會以守護執行緒(傳遞true給isDaemon變數)的方式執行。

(3)Timer(String name):建立一個新的定時器,其任務執行執行緒擁有指定的名稱且不會以守護執行緒的方式執行。

(4)Timer(String name, boolean isDaemon):建立一個新的定時器,其任務執行執行緒擁有指定的名稱且可能會以守護執行緒的方式執行。

(5)void cancel():終止該定時器,丟棄所有當前排程的定時器任務。

(6)int purge(): 從該定時器佇列中移除所有取消的定時任務並且返回被移除任務的數目。

(7)void schedule(TimerTask task, Date time): 在某個時間點排程任務執行。

(8)void schedule(TimerTask task, Date firstTime,long period): 排程任務於firstTime開始,以固定時間間隔的方式重複執行,後續以大約period毫秒數的固定時間間隔執行。在固定延遲執行中,每次執行都是相對於上次執行的實際發生時間的。當某次執行因為一些原因被延遲(比如垃圾回收),後續的執行也都會被延遲。

(9)void schedule(TimerTask task, long delay):在delay毫秒數之後排程任務執行。

(10)void schedule(TimerTask task,long delay,long period): 在delay毫秒數之後,以固定時間間隔的方式重複執行,後續以大約period毫秒數的固定時間間隔執行。

(11)void scheduleAtFixedRate(TimerTask task, Date firstTime, long period):  排程任務於firstTime開始,以固定速率的方式重複執行,後續以大約period毫秒數的固定時間間隔執行。

(12)void scheduleAtFixedRate(TimerTask task, long delay, long period): 在delay毫秒數之後,開始排程任務以固定速率的方式重複執行,後續以大約period毫秒數的固定時間間隔執行。

3. TimeTask類

boolean cancel(): 取消這個定時任務。

long scheduledExecutionTime(): 返回此定時任務最近實際被排程執行的時間。

4. Timer的cancel()的方法和TimerTask的cancel()方法的區別?

TimerTask類中的cancel()方法側重的是將自身從任務佇列中清除,其他任務不受影響,而Timer類中的cancel()方法則是將任務佇列中全部的任務清空。

TimerTask類中的cancel()方法測試:

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Test {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("當前時間為:" + new Date());
        Calendar c = Calendar.getInstance();
        Date runDate1 = c.getTime();
        System.out.println("計劃時間為:" + runDate1);
        MyTaskA task1 = new MyTaskA();
        MyTaskB task2 = new MyTaskB();
        Timer timer = new Timer();
        timer.schedule(task1, runDate1, 4000);
        timer.schedule(task2, runDate1, 4000);
    }
}

class MyTaskA extends TimerTask {

    @Override
    public void run() {
        System.out.println("A run timer=" + new Date());
        this.cancel();// 呼叫的是TimerTask類中的cancel()方法
        System.out.println("A任務自己移除自己,B任務不受影響,繼續執行");
    }

}

class MyTaskB extends TimerTask {

    @Override
    public void run() {
        System.out.println("B run timer=" + new Date());
    }

}

執行結果:

當前時間為:Tue Nov 20 21:25:30 CST 2018
計劃時間為:Tue Nov 20 21:25:30 CST 2018
A run timer=Tue Nov 20 21:25:30 CST 2018
A任務自己移除自己,B任務不受影響,繼續執行
B run timer=Tue Nov 20 21:25:30 CST 2018
B run timer=Tue Nov 20 21:25:34 CST 2018

Timer類中的cancel()方法測試:

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Test {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("當前時間為:" + new Date());
        Calendar c = Calendar.getInstance();
        Date runDate1 = c.getTime();
        System.out.println("計劃時間為:" + runDate1);
        MyTaskA task1 = new MyTaskA();
        MyTaskB task2 = new MyTaskB();
        Timer timer = new Timer();
        timer.schedule(task1, runDate1, 4000);
        timer.schedule(task2, runDate1, 4000);
         Thread.sleep(12000);
         timer.cancel();
         System.out.println("A、B任務都移除了");

    }
}

class MyTaskA extends TimerTask {

    @Override
    public void run() {
        System.out.println("A run timer=" + new Date());
    }

}

class MyTaskB extends TimerTask {

    @Override
    public void run() {
        System.out.println("B run timer=" + new Date());
    }

}

執行結果: 

 當前時間為:Tue Nov 20 21:29:03 CST 2018
計劃時間為:Tue Nov 20 21:29:03 CST 2018
A run timer=Tue Nov 20 21:29:03 CST 2018
B run timer=Tue Nov 20 21:29:03 CST 2018
B run timer=Tue Nov 20 21:29:07 CST 2018
A run timer=Tue Nov 20 21:29:07 CST 2018
A run timer=Tue Nov 20 21:29:11 CST 2018
B run timer=Tue Nov 20 21:29:11 CST 2018
A、B任務都移除了