• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統計

            最新評論

            Java:如何正確使用Timer

            在需要按時間計劃執行簡單任務的情況下,Timer是最常被使用到的工具類。使用Timer來調度TimerTask的實現者來執行任務,有兩種方式,一種是使任務在指定時間被執行一次,另一種是從某一指定時間開始周期性地執行任務。
             
            下面是一個簡單的Timer例子,它每隔10秒鐘執行一次特定操作doWork。
            Timer timer = new Timer();
                                    TimerTask  task = new TimerTask (){
                                    public void run() {
                                         doWork();
                                       }
            };
                          timer.schedule (task, 10000L, 10000L);
            可以看到,具體的任務由TimerTask的子類實現,Timer負責管理、執行TimerTask。
             
            Timer 的使用
            在不同的場景下,需要使用不同的Timer接口。如上所說,主要區分兩種情況
            1) 在指定時間執行任務,只執行一次
            -          public void schedule(TimerTask task, long delay)
            -          public void schedule(TimerTask task, Date time)
             
            2)從指定時間開始,周期性地重復執行,直到任務被cancel掉。其中又分兩種類型:
            2.1) 一種是按上一次任務執行的時間為依據,計算本次執行時間,可以稱為相對時間法。比如,如果第一次任務是1分10秒執行的,周期為5秒,因系統繁忙(比如垃 圾回收、虛擬內存切換),1分15秒沒有得到機會執行,直到1分16秒才有機會執行第二次任務,那么第3次的執行時間將是1分21秒,偏移了1秒。
            -          public void schedule(TimerTask task, long delay, long period)
            -          public void schedule(TimerTask task, Date firstTime, long period)
             
            2.2) 另一種是絕對時間法,以用戶設計的起始時間為基準,第n次執行時間為“起始時間+n*周期時間”。比如,在上面的情況下,雖然因為系統繁忙,第二執行時間被推后1秒,但第3次的時間點仍然應該是1分20秒。
            -          public void scheduleAtFixedRate(TimerTask task, long delay, long period)
            -          public void scheduleAtFixedRate(TimerTask task, Date firstTime,                                    long period)
             
            相 對時間法,關注于滿足短時間內的執行間隔,絕對時間法,則更關注在一個長時間范圍內,任務被執行的次數。如果我們要編寫一個程序,用timer控制文檔編 輯器中提示光標的閃爍,用哪種更合適? 當然是相對時間法。如果改用絕對時間法,當從系統繁忙狀態恢復后,光標會快速連續閃爍多次,以彌補回在系統繁忙期間沒有被執行的任務,這樣的情況會用戶來 說比較難以接受。又如,每10分鐘檢查一次新郵件的到來,也適合于使用相對時間法。
            Timer timer = new Timer();
                                    TimerTask  task = new TimerTask (){
                                     public void run() {
                                            displayCursor();
                                       }
            };
                          timer.schedule (task, 1000L, 1000L); //每秒閃爍一次光標
             
            作為對比,我們來考慮一種絕對時間法的應用場景——倒數任務,比如,要求在10秒內做倒數計時,每秒做一次doworkPerSecond操作,10秒結束時做一次doworkEnd操作,然后結束任務。
            Timer timer = new Timer();
                                    TimerTask  task = new TimerTask (){
                                          private int count=10;
                                          public void run() {
                                               if(count>0){
                                                  doWorkPerSecond();
                                                 count--;
                                        }else{
                                           doWorkEnd();
                                           cancel();
                                         }
                                       }
            };
                                    timer. scheduleAtFixedRate (task, 1000L, 1000L);
            Timer及相關類的內部實現
            Timer的內部會啟動一個線程TimerThread。即使有多個任務被加入這個Timer,它始終只有一個線程來管理這些任務。
            -          TimerThread是Thread的子類。加入Timer的所有任務都會被最終放入TimerThread所管理的TaskQueue中。 TimerThread會不斷查看TaskQueue中的任務,取出當前時刻應該被執行的任務執行之,并且會重新計算該任務的下一次執行時間,重新放入 TaskQueue。直到所有任務執行完畢(單次任務)或者被cancel(重復執行的任務),該線程才會結束。
            -          TaskQueue,由數組實現的二叉堆,堆的排序是以任務的下一次執行時間為依據的。二叉堆的使用使得TimerThread以簡潔高效的方式快速找到 當前時刻需要執行的TimerTask,因為,堆排序的特性是保證最?。ɑ蛘咦畲螅┲滴挥诙询B頂端,在這里,queue[1]始終是下次執行時間 (nextExecutionTime)最小的,即應該最先被執行的任務
             
            比如,同一個timer管理兩個任務task1和task2
            timer.schedule (task1, 4000L, 10000L);
            timer. scheduleAtFixedRate (task2, 2000L, 15000L);
            則,TaskQueue 中會有兩個任務:task1和task2。task2會排在頭部queue[1],當task2執行時間到,task2被執行,同時修改其 nextExecutionTime =當前的nextExecutionTime +15000L(絕對時間法)并重新在二叉堆中排序。排序后,task1被放到頭部。當task1執行時間到,task1被執行,并修改其 nextExecutionTime =當前時間+10000L,然后重新在二叉堆中對其排序………
             
            一個例子
            當收到客戶端請求時,服務端生成一個Response對象。服務端希望客戶端訪問該對象的間隔時間不能超過20秒,否則,服務端認為客戶端已經異常關閉或者網絡異常,此時銷毀掉該對象并打印錯誤日志。每次訪問都會重新開始計時。
             
            class Response{
            private TimerTask  timeout;
                        public void init(){
                     ………
            Timer timer = new Timer();
            timeout = new TimeOutTask();
                                    timer.schedule (timeout, 20000L);
            }
             
            public void invoke(){
                timeout.cancel();//取消當前的timeout任務
            ; ….
               timeout = new TimeOutTask();
                                       timer.schedule (timeout, 20000L);//重新開始計時
            }
             
            void destroy(){
               ……..
            }
             
            class TimeOutTask extends TimerTask{
                       public void run() {
            TraceTool.error(“Time out, destroy the Response object.”);
            destroy();
                                       }
            }
            }
             
            因為Timer不支持對任務重置計時,所以此處采取了先cancel當前的任務再重新加入新任務來達到重置計時的目的。注意,對一個已經cancel的任務,不能通過schedule重新加入Timer中執行。TimerTask的狀態機如下:
             

            一個新生成的TimerTask其狀態為VIRGIN,Timer只接受狀態為VIRGIN的任務,否則會有IllegalStateException異常拋出。
            調用任務的cancel方法,該任務就轉入CANCELLED狀態,并很快從TaskQueue中刪除。對單次執行的任務,一旦執行結束,該任務也會從中刪除。這意味著TimerTask將不再被timer所執行了。


            本文來源【學網】網站鏈接是http://www.xue5.com

            posted on 2012-06-10 00:14 大龍 閱讀(12347) 評論(0)  編輯 收藏 引用

            久久久久久免费一区二区三区| 中文国产成人精品久久不卡| 一级做a爰片久久毛片毛片| 久久精品人人做人人爽电影蜜月| 无码国内精品久久人妻麻豆按摩| 日本加勒比久久精品| 欧美日韩精品久久久久| 国内精品久久久久影院老司| 亚洲人成精品久久久久| 无码人妻久久一区二区三区免费丨| 久久精品卫校国产小美女| 久久免费国产精品一区二区| 久久久久久一区国产精品| 亚洲中文字幕无码久久综合网 | 国产精品无码久久综合| 国产精品美女久久久免费| 偷偷做久久久久网站| 久久综合欧美成人| 国产成人综合久久精品红| 国产精品午夜久久| 18岁日韩内射颜射午夜久久成人 | 国内精品久久久久影院老司| 99久久久国产精品免费无卡顿| 亚洲午夜福利精品久久| 精品久久久久久| 久久99国产综合精品| 久久影视国产亚洲| 国产精品99久久不卡| 久久99精品国产99久久6男男| 久久影院久久香蕉国产线看观看| 久久99国产综合精品女同| 99精品国产免费久久久久久下载| 麻豆国内精品久久久久久| 26uuu久久五月天| 国产99久久久久久免费看 | 久久人人青草97香蕉| 久久久久久久综合综合狠狠| 色婷婷综合久久久中文字幕| 久久国产精品成人影院| 久久99九九国产免费看小说| 日韩AV毛片精品久久久|