1.Timer 是線程安全的,會爲每一個定時任務調用一個線程(通過構造方法啓動線程),這些線程共享Timer對象;
2.通過Object.wait(long);來進行任務的安排;
3.此類可擴展到大量同時安排的任務(存在數千個都沒有問題)。在內部,它使用二進制堆來表示其任務隊列,所以安排任務的開銷是 O(log n),其中 n 是同時安排的任務數。
可通過JAVA API對其進行了解;
Timer 固定延遲加載和固定速率加載的區別:
執行類:
public class TimerMain {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
Timer time = new Timer("time-1");
time.scheduleAtFixedRate(new TimeTest(0), new Date(), 5000);
Timer time1 = new Timer("time-2");
time1.schedule(new TimeTest(0), new Date(), 5000);
}
}
Time任務實現類:
public class TimeTest extends TimerTask{
private int number = 0;
public TimeTest(int number){
this.number = number;
}
public void run() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
try {
if(number % 10 == 0){
System.out.println(Thread.currentThread().getName() + " ----- " + number + "----timertask run. " + sdf.format(new Date()));
Thread.sleep(6000);
}
number ++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
結果:
time-1 ----- 0----timertask run. 14:31:02
time-2 ----- 0----timertask run. 14:31:02
time-1 ----- 10----timertask run. 14:31:52
time-2 ----- 10----timertask run. 14:31:53
time-1 ----- 20----timertask run. 14:32:42
time-2 ----- 20----timertask run. 14:32:44
time-1 ----- 30----timertask run. 14:33:32
time-2 ----- 30----timertask run. 14:33:35
time-1 ----- 40----timertask run. 14:34:22
time-2 ----- 40----timertask run. 14:34:26
time-1 ----- 50----timertask run. 14:35:12
time-2 ----- 50----timertask run. 14:35:17
time-1 ----- 60----timertask run. 14:36:02
time-2 ----- 60----timertask run. 14:36:08
time-1 ----- 70----timertask run. 14:36:52
time-2 ----- 70----timertask run. 14:36:59
通過結果可以發現固定延遲加載會根據每次實際執行的時間來確定下次開始的時間,如果實際執行時間大於週期時間,則下次開始時間將延遲;
固定速率加在的加載時間也會根據執行時間要改變,如果某一次的執行時間大於週期時間則下次執行時間將延遲,但是在其後的運行中會減少週期時間來讓開始執行時間恢復的正常水平,因而可能會出現幾次任務密集加載的情況;
所以一般對於光標的閃爍、鍵盤定時輸入等會使用固定延遲加載;需要有固定性較強的時間週期如鐘錶的行走需要使用固定速率加載。