線程和線程池

多線程編程是業(yè)務(wù)開發(fā)中要用到的一項(xiàng)技術(shù),盡管面臨著一些挑戰(zhàn)劫拢,但多線程開發(fā)也有著很多優(yōu)點(diǎn)芜赌,例如資源利用率更好咖耘,程序設(shè)計(jì)在某些情況下更簡(jiǎn)單,程序響應(yīng)更快等等。接下來(lái)主要說(shuō)一下線程的幾種創(chuàng)建方式以及線程池的應(yīng)用维蒙。

1通過(guò)繼承Thread的方式來(lái)創(chuàng)建線程


2通過(guò)實(shí)現(xiàn)Runnable接口來(lái)創(chuàng)建線程


這兩種方式本質(zhì)上其實(shí)是一樣的掰吕,都是通過(guò)run()方法,深挖源碼的話颅痊,第一種方式中Thread其實(shí)也是實(shí)現(xiàn)了Runnable接口殖熟,然后重寫run()方法。然而這兩種方式有一個(gè)不足斑响,就是run()方法里并不能返回一個(gè)結(jié)果和拋出異常菱属,所以就有了第三種創(chuàng)建線程的方式,通過(guò)Callable接口恋捆,并用FutureTask來(lái)接收返回的對(duì)象照皆。

3通過(guò)Callable接口,并用FutureTask來(lái)接收返回的對(duì)象


和Runnable接口不一樣沸停,Callable接口提供了一個(gè)call()方法作為線程執(zhí)行體膜毁,call()方法比run()方法功能要強(qiáng)大。call()方法可以有返回值愤钾,call()方法可以聲明拋出異常

Java5提供了Future接口來(lái)代表Callable接口里call()方法的返回值瘟滨,并且為Future接口提供了一個(gè)實(shí)現(xiàn)類FutureTask,這個(gè)實(shí)現(xiàn)類既實(shí)現(xiàn)了Future接口能颁,還實(shí)現(xiàn)了Runnable接口杂瘸,因此可以作為Thread類的target。在Future接口里定義了幾個(gè)公共方法來(lái)控制它關(guān)聯(lián)的Callable任務(wù)伙菊。

接下來(lái)說(shuō)線程池败玉,線程池是管理線程的地方,在一個(gè)項(xiàng)目中镜硕,我們知道需要多次的創(chuàng)建線程和銷毀線程运翼,然而創(chuàng)建和銷毀是及其耗費(fèi)內(nèi)存資源的,所以就有了線程池的需要兴枯,來(lái)幫我們管理調(diào)度線程血淌,省下了很多的內(nèi)存資源。

我們應(yīng)該如何創(chuàng)建一個(gè)線程池那?Java中已經(jīng)提供了創(chuàng)建線程池的一個(gè)類:Executor

而我們創(chuàng)建時(shí)财剖,一般使用它的子類:ThreadPoolExecutor悠夯。但是從ThreadPoolExecutor到Executor并不是簡(jiǎn)單的實(shí)現(xiàn)或繼承關(guān)系,兩者中間有好多中間類躺坟。下面是各類之間的層級(jí)關(guān)系調(diào)用實(shí)現(xiàn)類圖


線程池類圖

我把這幾個(gè)類用黑色線條畫了起來(lái)沦补,發(fā)現(xiàn)我們需要的ThreadPoolExecutor首先繼承了抽象類AbstractExecutorService,然后AbstractExecutorService實(shí)現(xiàn)了ExecutorService接口咪橙,最ExecutorService接口又實(shí)現(xiàn)了Executor接口策彤。

我們?cè)賮?lái)看一下ThreadPoolExecutor構(gòu)造函數(shù)的參數(shù)


我們可以看出栓袖,線程池中的corePoolSize就是線程池中的核心線程數(shù)量,這幾個(gè)核心線程店诗,只是在沒有用的時(shí)候裹刮,也不會(huì)被回收,maximumPoolSize就是線程池中可以容納的最大線程的數(shù)量庞瘸,而keepAliveTime捧弃,就是線程池中除了核心線程之外的其他的最長(zhǎng)可以保留的時(shí)間,因?yàn)樵诰€程池中擦囊,除了核心線程即使在無(wú)任務(wù)的情況下也不能被清除违霞,其余的都是有存活時(shí)間的,意思就是非核心線程可以保留的最長(zhǎng)的空閑時(shí)間瞬场,而util买鸽,就是計(jì)算這個(gè)時(shí)間的一個(gè)單位,workQueue贯被,就是等待隊(duì)列眼五,任務(wù)可以儲(chǔ)存在任務(wù)隊(duì)列中等待被執(zhí)行,執(zhí)行的是FIFIO原則(先進(jìn)先出)彤灶。threadFactory看幼,就是創(chuàng)建線程的線程工廠,最后一個(gè)handler,是一種拒絕策略幌陕,我們可以在任務(wù)滿了之后诵姜,拒絕執(zhí)行某些任務(wù),具體的拒絕策略如下:

ThreadPoolExecutor.AbortPolicy:丟棄任務(wù)并拋出RejectedExecutionException異常搏熄。

ThreadPoolExecutor.DiscardPolicy:也是丟棄任務(wù)棚唆,但是不拋出異常。

ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊(duì)列最前面的任務(wù)心例,然后重新嘗試執(zhí)行任務(wù)(重復(fù)此過(guò)程)

ThreadPoolExecutor.CallerRunsPolicy:由調(diào)用線程處理該任務(wù)

再來(lái)看線程池的執(zhí)行流程


線程池的執(zhí)行流程

我們可以看出宵凌,任務(wù)進(jìn)來(lái)時(shí),首先執(zhí)行判斷契邀,判斷核心線程是否處于空閑狀態(tài)摆寄,如果不是失暴,核心線程就先就執(zhí)行任務(wù)坯门,如果核心線程已滿,則判斷任務(wù)隊(duì)列是否有地方存放該任務(wù)逗扒,若果有古戴,就將任務(wù)保存在任務(wù)隊(duì)列中,等待執(zhí)行矩肩,如果滿了现恼,在判斷最大可容納的線程數(shù),如果沒有超出這個(gè)數(shù)量,就開創(chuàng)非核心線程執(zhí)行任務(wù)叉袍,如果超出了始锚,就調(diào)用handler實(shí)現(xiàn)拒絕策略。

下面一段測(cè)試代碼來(lái)說(shuō)明這個(gè)線程池執(zhí)行的流程


最后運(yùn)行結(jié)果與執(zhí)行流程是一樣的喳逛,都是先判斷核心線程瞧捌,當(dāng)核心線程最大后,在判斷隊(duì)列润文,當(dāng)隊(duì)列也滿后姐呐,在進(jìn)入非核心線程。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末典蝌,一起剝皮案震驚了整個(gè)濱河市曙砂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌骏掀,老刑警劉巖鸠澈,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異砖织,居然都是意外死亡款侵,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門侧纯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)新锈,“玉大人,你說(shuō)我怎么就攤上這事眶熬∶冒剩” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵娜氏,是天一觀的道長(zhǎng)拳缠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)贸弥,這世上最難降的妖魔是什么窟坐? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮绵疲,結(jié)果婚禮上哲鸳,老公的妹妹穿的比我還像新娘。我一直安慰自己盔憨,他們只是感情好徙菠,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著郁岩,像睡著了一般婿奔。 火紅的嫁衣襯著肌膚如雪缺狠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天萍摊,我揣著相機(jī)與錄音挤茄,去河邊找鬼。 笑死冰木,一個(gè)胖子當(dāng)著我的面吹牛驮樊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播片酝,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼囚衔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了雕沿?” 一聲冷哼從身側(cè)響起练湿,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎审轮,沒想到半個(gè)月后肥哎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疾渣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年篡诽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片榴捡。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杈女,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吊圾,到底是詐尸還是另有隱情达椰,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布项乒,位于F島的核電站啰劲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏檀何。R本人自食惡果不足惜蝇裤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望频鉴。 院中可真熱鬧栓辜,春花似錦、人聲如沸砚殿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)似炎。三九已至辛萍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間羡藐,已是汗流浹背贩毕。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仆嗦,地道東北人辉阶。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瘩扼,于是被迫代替她去往敵國(guó)和親谆甜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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

  • Android中的線程 線程集绰,在Android中是非常重要的规辱,主線程處理UI界面,子線程處理耗時(shí)操作栽燕。如果在主線程...
    shenhuniurou閱讀 750評(píng)論 0 3
  • 不同形式的線程雖然都是線程罕袋,但是它們?nèi)匀痪哂胁煌奶匦院蛯?shí)用場(chǎng)景: AsyncTask封裝了線程池和Handler...
    胡二囧閱讀 1,112評(píng)論 0 4
  • 一.Java中的ThreadPoolExecutor類 java.uitl.concurrent.ThreadPo...
    誰(shuí)在烽煙彼岸閱讀 643評(píng)論 0 0
  • 導(dǎo)語(yǔ) 在Android系統(tǒng),線程主要分為主線程和子線程碍岔,主線程處理和界面相關(guān)的事情浴讯,而子線程一般用于執(zhí)行耗時(shí)操作。...
    一個(gè)有故事的程序員閱讀 584評(píng)論 0 3
  • 1 你的樣子跟別人不同蔼啦。 每次點(diǎn)開運(yùn)動(dòng)的app榆纽,總是看到圈內(nèi)的人都在曬各種健身后的照片或撩腹部的照片。不記得聽誰(shuí)說(shuō)...
    聽風(fēng)想雨閱讀 311評(píng)論 5 1