Timer主要用於Java線程里指定時間或周期運行任務,它是線程安全的,但不提供實時性(real-time)保證。

上面提到了守護線程的概念。
Java分為兩種線程:用戶線程和守護線程。
所謂守護線程,是指在程序運行的時候在后台提供一種通用服務的線程,比如垃圾回收線程就是一個很稱職的守護者,並且這種線程並不屬於程序中不可或缺的部分。因 此,當所有的非守護線程結束時,程序也就終止了,同時會殺死進程中的所有守護線程。反過來說,只要任何非守護線程還在運行,程序就不會終止。
守護線程和用戶線程的唯一不同之處就在於虛擬機的離開:如果用戶線程已經全部退出運行了,只剩下守護線程存在了,虛擬機也就退出了。 因為沒有了被守護者,守護線程也就沒有工作可做了,也就沒有繼續運行程序的必要了。
將線程轉換為守護線程可以通過調用Thread對象的setDaemon(true)方法來實現。在使用守護線程時需要注意以下幾點:
(1) thread.setDaemon(true)必須在thread.start()之前設置,否則會跑出一個IllegalThreadStateException異常。你不能把正在運行的常規線程設置為守護線程。
(2) 在Daemon線程中產生的新線程也是Daemon的。
(3) 守護線程應該永遠不去訪問固有資源,如文件、數據庫,因為它會在任何時候甚至在一個操作的中間發生中斷。

我們接下來寫個案例,使得程序運行3秒后在控制台打印輸出“該起床了”。
package com.itszt.test7;
import java.text.SimpleDateFormat;
import java.util.Timer;
import java.util.TimerTask;
/**
* Java計時器
*/
public class TimerTest {
static String str="HH:mm:ss";
static SimpleDateFormat dateFormat = new SimpleDateFormat(str);
public static void main(String[] args) {
Timer timer = new Timer();
String now1 = dateFormat.format(System.currentTimeMillis());
System.out.println(now1);
//延遲3秒后執行任務
timer.schedule(new MyTask(),3000);//單位是毫秒
}
}
class MyTask extends TimerTask{
@Override
public void run() {
System.out.println("該起床了");
String now2 = TimerTest.dateFormat.format(System.currentTimeMillis());
System.out.println(now2);
}
}
上述代碼執行后,延遲3秒打印出“該起床了”,如下所示:
21:26:18 該起床了 21:26:21
Timer的其他方法:
schedule(TimerTask task, Date time) 在指定的日期執行一次TimerTask任務;如果日期time早於當前時間,則立刻執行。
schedule(TimerTask task, long delay, long period) 以當前時間為基准,延遲指定的毫秒后,再按指定的時間間隔地無限次數的執行TimerTask任務。
schedule(TimerTask task, Date firstTime, long period) 在指定的日期之后,按指定的時間間隔地無限次數的執行TimerTask任務。
scheduleAtFixedRate(TimerTask task, long delay, long period) 以當前時間為基准,延遲指定的毫秒后,再按指定的時間間隔周期性地無限次數的執行TimerTask任務。
