通俗易懂的Java線(xiàn)程池技術(shù)

最近在給小伙伴說(shuō)明線(xiàn)程池技術(shù)的時(shí)候恩急,用到了一個(gè)例子假栓,發(fā)現(xiàn)比較適合匾荆,在這記錄一下。

很多書(shū)籍和文章都會(huì)說(shuō)牙丽,如果請(qǐng)求很多的話(huà)烤芦,頻繁的創(chuàng)建和銷(xiāo)毀線(xiàn)程容易造成資源的消耗和浪費(fèi)构罗,降低系統(tǒng)的響應(yīng),這個(gè)時(shí)候遂唧,需要對(duì)線(xiàn)程進(jìn)行的統(tǒng)一分配盖彭、監(jiān)控、管理铺呵,線(xiàn)程池技術(shù)就派上用場(chǎng)了。

先看一下Java中關(guān)于線(xiàn)程池 ThreadPoolExecutor 的創(chuàng)建

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

分別對(duì)這幾個(gè)參數(shù)做一個(gè)說(shuō)明:

  • corePoolSize :核心線(xiàn)程數(shù),線(xiàn)程池中可以長(zhǎng)期存在的線(xiàn)程數(shù)量贱鼻,即使沒(méi)有任務(wù)提交到線(xiàn)程池滋将,也不會(huì)被銷(xiāo)毀。
  • maximumPoolSize :最大線(xiàn)程數(shù)父丰,線(xiàn)程池中最多可以創(chuàng)建來(lái)執(zhí)行任務(wù)的線(xiàn)程上限蛾扇。
  • keepAliveTime :存活時(shí)間,超過(guò) maximumPoolSize 數(shù)量外的線(xiàn)程的存活時(shí)間坟漱,超過(guò)這個(gè)時(shí)間沒(méi)有執(zhí)行任務(wù)時(shí)會(huì)被銷(xiāo)毀芋齿。
  • TimeUnit : keepAliveTime 的單位成翩。
  • workQueue : 任務(wù)隊(duì)列,沒(méi)有得到執(zhí)行的任務(wù)栅炒,會(huì)放入這個(gè)隊(duì)列中等待空閑的線(xiàn)程來(lái)執(zhí)行它赢赊。
  • threadFactory : 線(xiàn)程工廠(chǎng)级历,定義創(chuàng)建新線(xiàn)程的方式鱼喉,包括線(xiàn)程名稱(chēng),線(xiàn)程組等锋边。
  • handler :拒絕策略豆巨,當(dāng) workQueue 已滿(mǎn)掐场,并且 線(xiàn)程數(shù)量達(dá)到了maximumPoolSize熊户,會(huì)對(duì)新提交的任務(wù)執(zhí)行拒絕策略。

再來(lái)看看線(xiàn)程池的工作原理:

  • 如果線(xiàn)程池中的線(xiàn)程數(shù)量沒(méi)超過(guò)corePoolSize蝗罗,創(chuàng)建一個(gè)新線(xiàn)程來(lái)執(zhí)行任務(wù)串塑。
  • 如果線(xiàn)程池中的線(xiàn)程數(shù)量達(dá)到corePoolSize,將任務(wù)放入workQueue桩匪。
  • 如果workQueue已滿(mǎn),線(xiàn)程池中的線(xiàn)程數(shù)量沒(méi)超過(guò)maximumPoolSize瑟慈,創(chuàng)建新線(xiàn)程來(lái)執(zhí)行任務(wù)葛碧。
  • 線(xiàn)程池中的線(xiàn)程執(zhí)行完一個(gè)任務(wù)后进泼,會(huì)從workQueue取任務(wù)執(zhí)行。
  • 超過(guò)corePoolSize的線(xiàn)程如果空閑超過(guò)keepAliveTime沒(méi)有執(zhí)行任務(wù)纤虽,就要進(jìn)行銷(xiāo)毀乳绕。
  • 如果workQueue已滿(mǎn),且線(xiàn)程池中的線(xiàn)程數(shù)量達(dá)到maximumPoolSize逼纸,執(zhí)行拒絕策略 handler洋措。

- - - - - - - - - - - - - - 這是一個(gè)分割線(xiàn) - - - - - - - - - - - - -

上邊就是官網(wǎng)中對(duì)線(xiàn)程池參數(shù)的一些說(shuō)明,這一個(gè)個(gè)參數(shù)看起來(lái)都什么玩意兒杰刽,說(shuō)的是人話(huà)嗎菠发,好吧,那我們用生活中的例子來(lái)重新說(shuō)明一下贺嫂。

首先滓鸠,為什么要是用線(xiàn)程池技術(shù),為什么說(shuō)創(chuàng)建和銷(xiāo)毀線(xiàn)程會(huì)消耗資源

讓我們想象一下第喳,有一個(gè)旅游村(假設(shè)叫象牙村吧)住著一戶(hù)人家曲饱,就叫 老王 吧(不是老王八)楔敌,經(jīng)常有來(lái)旅游的人來(lái)化個(gè)緣吃個(gè)飯侵浸,這時(shí)候,老王把桌子椅子擺上值漫,讓這個(gè)人坐好沥邻,然后根據(jù)這個(gè)人的需要把他要吃的飯做好埃跷,等這個(gè)人吃完飯走了之后,把桌子椅子收拾好剪勿。假設(shè)來(lái)吃飯的人不多的話(huà)還好,來(lái)一個(gè)人就臨時(shí)擺個(gè)桌子椅子就行赴涵;但是如果來(lái)吃飯的人很多,每次都要先把椅子擺好,等一個(gè)人吃完程拭,把桌椅收起來(lái)崖媚,再把桌椅搬出來(lái)給下一個(gè)人用,這樣反反復(fù)復(fù)荠呐,很浪費(fèi)搬桌子的時(shí)間。這個(gè)時(shí)候,老王想:來(lái)旅游人也挺多的钞钙,我干脆開(kāi)個(gè)飯店得了。

線(xiàn)程池技術(shù)應(yīng)運(yùn)而生:

  • 線(xiàn)程就相當(dāng)于吃飯的桌子焕议,每張桌子要配備一個(gè)服務(wù)員
  • 飯店就相當(dāng)于線(xiàn)程池

接著,線(xiàn)程池里的參數(shù)對(duì)應(yīng)過(guò)來(lái)代表什么意思:

  • corePoolSize :飯店大廳的桌子數(shù),能供多少人共同吃飯蝙寨,就算沒(méi)人來(lái)吃飯贝奇,這個(gè)桌子也不會(huì)收起來(lái)毕源。
  • maximumPoolSize :最多桌子數(shù),大廳坐不下了必盖,飯店在院子里再擺新的桌子拍埠。
  • keepAliveTime :存活時(shí)間,院子里的桌子多長(zhǎng)時(shí)間沒(méi)人用了棉圈,就要收起來(lái)。
  • TimeUnit : keepAliveTime 的單位吁系。
  • workQueue : 飯店大廳坐滿(mǎn)了的話(huà)蕴坪,就要先排隊(duì)呆瞻。
  • threadFactory : 生產(chǎn)桌子的方式,知道是哪個(gè)飯店第幾桌买窟。這個(gè)有什么用呢话侄?如果不指定的話(huà)吞杭,假設(shè)老王開(kāi)了個(gè)飯店童擎,老李開(kāi)了個(gè)飯店芯砸,他們都沒(méi)有自己指定的桌子供貨商,那就默認(rèn)使用村子里生產(chǎn)的桌子,按順序的話(huà)就是 象牙村1號(hào)桌象牙村2號(hào)桌,萬(wàn)一發(fā)生了意外,客人吃著吃著肚子不舒服矾策,或者這一桌的客人喝大了打了起來(lái)蓬豁,只知道是 象牙村X(qián)號(hào)桌 出了問(wèn)題,不知道該找老王還是老李矛辕,但是如果他們有自己的供貨商翻屈,桌子就變成了老王飯店1號(hào)桌惊窖,老李飯店9號(hào)桌毁欣,出了問(wèn)題串述,能夠溯源。所以一般建議大家使用自己的線(xiàn)程工廠(chǎng),按業(yè)務(wù)對(duì)線(xiàn)程進(jìn)行命名欣簇。
  • handler :當(dāng)排隊(duì)的隊(duì)伍排滿(mǎn)了闹丐,院子里也坐滿(mǎn)了人,就要對(duì)新來(lái)的人執(zhí)行拒絕策略缘挽。

最后摹蘑,看看怎么用這個(gè)例子來(lái)解釋線(xiàn)程池的工作原理:

  • 有一個(gè)客人要來(lái)吃飯的時(shí)候踪少,如果飯店大廳沒(méi)有坐滿(mǎn),就在大廳擺上桌椅纬霞,讓這個(gè)客人吃飯。
  • 如果大廳坐滿(mǎn)了横蜒,新來(lái)的人就要在門(mén)口的椅子上坐著排隊(duì)茵乱,等待輪到自己的順序次询,這個(gè)椅子可以限制數(shù)量,比如只排50個(gè)人,也可以不限制虹蓄。
  • 如果門(mén)口排隊(duì)的椅子已經(jīng)坐滿(mǎn)了累铅,說(shuō)明今天來(lái)吃飯的人實(shí)在太多娃兽,老王就要看看還有沒(méi)有多余的桌子玛荞,有的話(huà)客蹋,就在院子里把桌子擺上給新來(lái)的人吃飯娩井。
  • 一旦某一桌的客人吃完走了之后仔粥,這張桌子服務(wù)員就會(huì),就從門(mén)口排隊(duì)的客人里讓最靠前的進(jìn)店吃飯蟹但。
  • 院子里的桌子如果一段時(shí)間沒(méi)人吃飯躯泰,說(shuō)明過(guò)了吃飯的高峰期,客人不那么多了华糖,超過(guò)keepAliveTime的空閑麦向,就要把桌子收起來(lái),這個(gè)服務(wù)員也回去休息客叉。
  • 如果門(mén)口排隊(duì)的椅子已經(jīng)坐滿(mǎn)诵竭,店里的桌子也都用完,要執(zhí)行相應(yīng)的拒絕策略兼搏。有這么幾種策略
    1. AbortPolicy :默認(rèn)的卵慰,拋出一個(gè)異常。相當(dāng)于用大喇叭喊了一下:“本店吃飯人數(shù)太多啦佛呻,大家別擠了”裳朋。
    2. DiscardPolicy :直接丟棄。相當(dāng)于跟客人說(shuō)吓著,現(xiàn)在人太多鲤嫡,不接待新客戶(hù)了。
    3. DiscardOldestPolicy :丟棄排隊(duì)最久的任務(wù)夜矗。相當(dāng)于讓門(mén)口椅子上排第一個(gè)的人出去泛范,意思是,你都排這么久了紊撕,看來(lái)你也不餓,那你就別吃了吧赡突。
    4. CallerRunsPolicy :接待者執(zhí)行对扶,意思就是在門(mén)口迎賓的那個(gè)人,把自己坐的桌子讓出來(lái)給客人吃飯惭缰,但在這個(gè)客人吃完之前浪南,他就沒(méi)法再接待新的客人了。

再補(bǔ)充一下關(guān)于停止線(xiàn)程池的2個(gè)方法漱受,這兩個(gè)方法都會(huì)拒絕新任務(wù)络凿,相當(dāng)于說(shuō)本店打烊了,不接待新客戶(hù),它們之間的區(qū)別在于:

  • shutdown() :允許在關(guān)店之前已經(jīng)來(lái)店里的客人把飯吃完絮记。
  • shutdownNow() :不但不讓正在排隊(duì)的客人進(jìn)店吃飯摔踱,還會(huì)嘗試把在店里沒(méi)吃完的客人趕出去。這個(gè)方法比較暴力怨愤。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末派敷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子撰洗,更是在濱河造成了極大的恐慌篮愉,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件差导,死亡現(xiàn)場(chǎng)離奇詭異试躏,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)设褐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)颠蕴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人络断,你說(shuō)我怎么就攤上這事裁替。” “怎么了貌笨?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵弱判,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锥惋,道長(zhǎng)昌腰,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任膀跌,我火速辦了婚禮遭商,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捅伤。我一直安慰自己劫流,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布丛忆。 她就那樣靜靜地躺著祠汇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪熄诡。 梳的紋絲不亂的頭發(fā)上可很,一...
    開(kāi)封第一講書(shū)人閱讀 49,792評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音凰浮,去河邊找鬼我抠。 笑死苇本,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的菜拓。 我是一名探鬼主播瓣窄,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尘惧!你這毒婦竟也來(lái)了康栈?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤喷橙,失蹤者是張志新(化名)和其女友劉穎啥么,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體贰逾,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悬荣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疙剑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氯迂。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖言缤,靈堂內(nèi)的尸體忽然破棺而出嚼蚀,到底是詐尸還是另有隱情,我是刑警寧澤管挟,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布轿曙,位于F島的核電站,受9級(jí)特大地震影響僻孝,放射性物質(zhì)發(fā)生泄漏导帝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一穿铆、第九天 我趴在偏房一處隱蔽的房頂上張望您单。 院中可真熱鬧,春花似錦荞雏、人聲如沸虐秦。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)羡疗。三九已至,卻和暖如春别洪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柳刮。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工挖垛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痒钝,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓痢毒,卻偏偏與公主長(zhǎng)得像送矩,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哪替,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

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