格式化

廣告

廣告2

2014年11月15日 星期六

[Android SDK特色教學] 計時器要用Timer和ScheduledExecutorService間抉擇

轉載至:http://sunnylocus.iteye.com/blog/530969
java.util.Timer計時器有管理任務延遲執行("如 1000ms後執行任務")以及週期性執行("如每500ms執行一次該任務")。但是,Timer存在一些缺陷,因此你應該考慮使用 ScheduledThreadPoolExecutor作為代替品,Timer對調度的支持是基於絕對時間,而不是相對時間的,由此任務對系統時鐘的改 變是敏感的;ScheduledThreadExecutor只支持相對時間。

Timer的另一個問題在於,如果TimerTask拋出未檢查的異常,Timer將會產生無法預料的行為。Timer線程並不捕獲異常,所以 TimerTask拋出的未檢查的異常會終止timer線程。這種情況下,Timer也不會再重新恢複線程的執行了;它錯誤的認為整個Timer都被取消 了。此時,已經被安排但尚未執行的TimerTask永遠不會再執行了,新的任務也不能被調度了。


所以timer的timetask只要不小心有例外,就會導致整個工作停止,永遠無法執行下個任務。反之,用ScheduledExecutorService就沒這種困擾,而且占用資源更少。

以下是範例程式碼:



import java.util.concurrent.Executors;  
import java.util.concurrent.ScheduledExecutorService;  
import java.util.concurrent.TimeUnit;  
  
public class ScheduledExecutorTest {  
    //線程池能按時間計划來執行任務,允許用戶設定計劃執行任務的時間,int類型的參數是設定  
    //線程池中線程的最小數目。當任務較多時,線程池可能會自動創建更多的工作線程來執行任務  
    public ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(1);  
    //啟動計時器  
    public void lanuchTimer(){  
        Runnable task = new Runnable() {  
            public void run() {  
                throw new RuntimeException();  
            }  
        };  
        scheduExec.scheduleWithFixedDelay(task, 1000*5, 1000*10, TimeUnit.MILLISECONDS);  
    }  
    //添加新任務  
    public void addOneTask(){  
        Runnable task = new Runnable() {  
            public void run() {  
                System.out.println("welcome to china");  
            }  
        };  
        scheduExec.scheduleWithFixedDelay(task, 1000*1, 1000, TimeUnit.MILLISECONDS);  
    }  
      
    public static void main(String[] args) throws Exception {  
        ScheduledExecutorTest test = new ScheduledExecutorTest();  
        test.lanuchTimer();  
        Thread.sleep(1000*5);//5秒鐘之後添加新任務  
        test.addOneTask();  
    }  
}  

沒有留言 :