Java:轉(zhuǎn)載——Timer與ScheduledExecutorService的區(qū)別

本文轉(zhuǎn)載自 http://blog.csdn.net/nalw2012/article/details/49633413

java.util.Timer計(jì)時(shí)器有管理任務(wù)延遲執(zhí)行("如1000ms后執(zhí)行任務(wù)")以及周期性執(zhí)行("如每500ms執(zhí)行一次該任務(wù)")癞蚕。但是,Timer存在一些缺陷辉哥,因此你應(yīng)該考慮使用ScheduledThreadPoolExecutor作為代替品.

  • Timer對調(diào)度的支持是基于絕對時(shí)間,而不是相對時(shí)間的桦山,由此任務(wù)對系統(tǒng)時(shí)鐘的改變是敏感的;ScheduledThreadExecutor只支持相對時(shí)間。

  • Timer的另一個(gè)問題在于,如果TimerTask拋出未檢查的異常度苔,Timer將會產(chǎn)生無法預(yù)料的行為匆篓。Timer線程并不捕獲異常浑度,所以TimerTask拋出的未檢查的異常會終止timer線程寇窑。這種情況下,Timer也不會再重新恢復(fù)線程的執(zhí)行了;它錯(cuò)誤的認(rèn)為整個(gè)Timer都被取消了箩张。此時(shí)甩骏,已經(jīng)被安排但尚未執(zhí)行的TimerTask永遠(yuǎn)不會再執(zhí)行了,新的任務(wù)也不能被調(diào)度了先慷。

個(gè)人總結(jié):timer的bug:60秒執(zhí)行一次的話饮笛,如果用戶修改了時(shí)間的話 那么時(shí)針都會歸0,本來是臨近10秒執(zhí)行的時(shí)候timer又會重新計(jì)時(shí)一次 再等60才執(zhí)行论熙。

測試Timer的例子

import java.util.Timer;    
import java.util.TimerTask;    
    
public class TimerTest {    
    private Timer timer = new Timer();    
    //啟動計(jì)時(shí)器    
    public void lanuchTimer(){    
        timer.schedule(new TimerTask(){    
            public void run() {    
                throw new RuntimeException();    
            }    
        }, 1000*3, 500);    
    }    
    //向計(jì)時(shí)器添加一個(gè)任務(wù)    
    public void addOneTask(){    
        timer.schedule(new TimerTask(){    
            public void run(){    
                System.out.println("hello world");    
            }    
        }, 1000*1,1000*5);    
    }    
        
    public static void main(String[] args) throws Exception {    
        TimerTest test = new TimerTest();    
        test.lanuchTimer();    
        Thread.sleep(1000*5);//5秒鐘之后添加一個(gè)新任務(wù)    
        test.addOneTask();    
    }    
}  

運(yùn)行該程序福青,Timer會拋出一個(gè)RumtimeException和java.lang.IllegalStateException:Timer already cancelled。常言道脓诡,真是禍不單行无午,Timer還將它的問題傳染給下一個(gè)倒霉的調(diào)用者,這個(gè)調(diào)用者原本試圖提交一個(gè)TimerTask的祝谚,你可能希望程序會一直運(yùn)行下去宪迟,然而實(shí)際情況如程序所示5秒鐘后就中止了,還伴隨著一個(gè)異常交惯,異常的消息是"Timer already cancelled"次泽。

ScheduledThreadPoolExector妥善地處理了這個(gè)異常的任務(wù),所以說在java5.0或更高的JDK中席爽,幾乎沒有理由再使用Timer了意荤。

用ScheduledThreadPoolExector改進(jìn)后的例子

    
import java.util.concurrent.Executors;    
import java.util.concurrent.ScheduledExecutorService;    
import java.util.concurrent.TimeUnit;    
    
public class ScheduledExecutorTest {    
    //線程池能按時(shí)間計(jì)劃來執(zhí)行任務(wù),允許用戶設(shè)定計(jì)劃執(zhí)行任務(wù)的時(shí)間只锻,int類型的參數(shù)是設(shè)定    
    //線程池中線程的最小數(shù)目玖像。當(dāng)任務(wù)較多時(shí),線程池可能會自動創(chuàng)建更多的工作線程來執(zhí)行任務(wù)    
    //此處用Executors.newSingleThreadScheduledExecutor()更佳炬藤。  
    public ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(1);    
    //啟動計(jì)時(shí)器    
    public void lanuchTimer(){    
        Runnable task = new Runnable() {    
            public void run() {    
                throw new RuntimeException();    
            }    
        };    
        scheduExec.scheduleWithFixedDelay(task, 1000*5, 1000*10, TimeUnit.MILLISECONDS);    
    }    
    //添加新任務(wù)    
    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秒鐘之后添加新任務(wù)    
        test.addOneTask();    
    }    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末御铃,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子沈矿,更是在濱河造成了極大的恐慌上真,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羹膳,死亡現(xiàn)場離奇詭異睡互,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門就珠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寇壳,“玉大人,你說我怎么就攤上這事妻怎】茄祝” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵逼侦,是天一觀的道長匿辩。 經(jīng)常有香客問我,道長榛丢,這世上最難降的妖魔是什么铲球? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮晰赞,結(jié)果婚禮上稼病,老公的妹妹穿的比我還像新娘。我一直安慰自己掖鱼,他們只是感情好然走,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锨用,像睡著了一般丰刊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上增拥,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天啄巧,我揣著相機(jī)與錄音,去河邊找鬼掌栅。 笑死秩仆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的猾封。 我是一名探鬼主播澄耍,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼晌缘!你這毒婦竟也來了齐莲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤磷箕,失蹤者是張志新(化名)和其女友劉穎选酗,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岳枷,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芒填,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年呜叫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殿衰。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡朱庆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闷祥,到底是詐尸還是另有隱情娱颊,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布蜀踏,位于F島的核電站维蒙,受9級特大地震影響掰吕,放射性物質(zhì)發(fā)生泄漏果覆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一殖熟、第九天 我趴在偏房一處隱蔽的房頂上張望局待。 院中可真熱鬧,春花似錦菱属、人聲如沸钳榨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽薛耻。三九已至,卻和暖如春赏陵,著一層夾襖步出監(jiān)牢的瞬間饼齿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工蝙搔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缕溉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓吃型,卻偏偏與公主長得像证鸥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子勤晚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容