Timer的優缺點
Timer 的優點在於簡單易用,但由於所有任務都是由同一個線程來調度,因此所有任務都是串行執行的,同一時間只能有一個任務在執行,前一個任務的延遲或異常都將會影響到之後的任務。
Timer和TimerTask存在一些缺陷:
- Timer只創建了一個線程。當你的任務執行的時間超過設置的延時時間將會產生一些問題。
- Timer創建的線程沒有處理異常,因此一旦拋出非受檢異常,該線程會立即終止。
用ScheduledThreadPoolExecutor來替代Timer
JDK 5.0以後推薦使用ScheduledThreadPoolExecutor。該類屬於Executor Framework,它除了能處理異常外,還可以創建多個線程解決上面的問題。
ScheduledThreadPoolExecutor是ThreadPoolExecutor的子類。按先進先出 (FIFO)順利處理那些安排在同一時間執行的任務。
- ThreadPoolExecutor可以另行安排在給定的延遲後運行命令,或者定期執行命令。
- 需要多個輔助線程時,或者要求 ThreadPoolExecutor 具有額外的靈活性或功能時,請使用ScheduledThreadPoolExecutor。
scheduleWithFixedDelay方法的使用
/**
* initialDelay:初始化延時
* delay:前一次執行結束到下一次執行開始的間隔時間
**/
scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit);
來個簡單例子
/**
* 第一次延遲10毫秒後執行,執行完延遲20毫秒後再執行
*/
scheduleWithFixedDelay(task,10,20,TimeUnit.MILLISECONDS);
示例代碼
static ScheduledThreadPoolExecutor stpe = null;
public static void main(String[] args) {
// 構造一個ScheduledThreadPoolExecutor對象,並且設置它的容量爲5個
stpe = new ScheduledThreadPoolExecutor(5);
MyTask task = new MyTask();
// 隔2秒後開始執行任務,並且在上一次任務開始後隔一秒再執行一次;
// stpe.scheduleWithFixedDelay(task, 2, 1, TimeUnit.SECONDS);
// 隔6秒後執行一次,但只會執行一次。
stpe.schedule(task, 6, TimeUnit.SECONDS);
}
private static class MyTask implements Runnable {
@Override
public void run() {
index++;
System.out.println("2= " + index);
if (index >= 10) {
stpe.shutdown();
if (stpe.isShutdown()) {
System.out.println("Shutdown");
}
}
}
}