昨天使用了 Executors 的 newScheduledThreadPool 和 newSingleThreadScheduledExecutor 方法建立了執行緒的 scheduled,可以在特定時間或是定期的時間內執行到執行緒。java.util 的 package 下也有提供 Timer 的類別,可以用來定期的執行程式。
Timer 比較適合使用一個執行緖執行,所以如果要開多執行緒執行適合使用昨天介紹的ScheduledExecutorService 類別來執行,以下來寫一個簡單的 Timer 的 sample code:
import java.util.TimerTask;
public class TimerTaskExample extends TimerTask {
private long startTime;
public TimerTaskExample(long startTime) {
this.startTime = startTime;
}
@Override
public void run() {
long runningTime = System.currentTimeMillis() - this.startTime;
System.out.println(runningTime);
}
}
以上是繼承 TimerTask 主要給 Timer 類別使用,TimerTask 是一個抽像類別實作了 Runnable 的介面,因此在實作 TimerTaskExample 的類別一樣會需要實作 run 的方法,以下是主程式的程式:
import java.util.Timer;
import java.util.TimerTask;
public class Test {
public static void main(String args[]) {
long startTime = System.currentTimeMillis();
TimerTask timerTask = new TimerTaskExample(startTime);
Timer timer = new Timer();
timer.scheduleAtFixedRate(timerTask, 1000, 5000);
}
}
main 程式裡使用 Timer 類別,然後呼叫了 scheduleAtFixedRate 方法,在執行程式時等待 1 秒之後,會每隔 5 秒的時間來執行 TimerTaskExample 的執行緒程式,執行的結果如下:
1052
6052
11052
16052
21053
26052
31052
36052
41052
46053
從以上的結果可以看出每隔 5 秒,會將值印出來
使用 Timer 有個缺點就是如果啟動二個 task 在執行時,如果有其中的一個 task 丟出一個 Exception 時另外一個 task 也會停止執行, Sample code 如下:
import java.util.TimerTask;
public class TimerTaskExceptionExample extends TimerTask {
@Override
public void run() {
throw new RuntimeException("Exception Test");
}
}
在這裡建立一個在執行 run 方法時會丟出 Exception 的 TimerTask
import java.util.Timer;
import java.util.TimerTask;
public class Test {
public static void main(String args[]) {
long startTime = System.currentTimeMillis();
TimerTask timerTask1 = new TimerTaskExample(startTime);
TimerTask timerTask2 = new TimerTaskExceptionExample();
Timer timer = new Timer();
timer.scheduleAtFixedRate(timerTask1, 1000, 2000);
timer.scheduleAtFixedRate(timerTask2, 3000, 5000);
}
}
在主程式呼叫的部份會建立了二個 task,當執行到 timerTask2 時會收到 Exception,這時程式就會暫停執行,timerTask1 也就不會被執行到,輸出的結果如下:
1002
Exception in thread "Timer-0" java.lang.RuntimeException: Exception Test
at TimerTaskExceptionExample.run(TimerTaskExceptionExample.java:6)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)