java線程池

線程池是一種池技術(shù)尺棋,就像連接池一樣封锉。線程池本身也是一個對象,這個對象可以管理自己池子中的眾多線程膘螟,以使他們被高效率的反復(fù)利用

  • 為何要使用線程池

  1. 降低資源消耗成福,防止資源不足。
    線程也是對象荆残,頻繁的創(chuàng)建線程對象奴艾,就會頻繁的去觸發(fā)內(nèi)存分配和內(nèi)存占用,大量消耗性能内斯,內(nèi)存占用過多可能會導(dǎo)致內(nèi)存溢出蕴潦。
    頻繁的創(chuàng)建和銷毀線程對象即頻繁的消耗cpu像啼,影響服務(wù)器性能。
    因為有大量的對象產(chǎn)生品擎,就會有大量的GC回收埋合,大量的gc可能會導(dǎo)致gc抖動,卡頓等現(xiàn)象萄传,也會影響服務(wù)器性能甚颂。
  2. 提高響應(yīng)速度
    當(dāng)需要被線程執(zhí)行的任務(wù)到達時,因線程池中已有創(chuàng)建好的線程秀菱,所以可以直接用創(chuàng)建好的線程去執(zhí)行任務(wù)振诬,而無需先創(chuàng)建一個線程,然后在執(zhí)行任務(wù)衍菱,節(jié)省了程序運行時間赶么。
  3. 提高線程的可管理性
    可以控制線程的數(shù)量和并法數(shù),也可以防止無限制的創(chuàng)建線程數(shù)量導(dǎo)致性能和內(nèi)存溢出等問題脊串。
  4. 提供更強大的功能辫呻,延時定時線程池
    比如,我們需要一個任務(wù)每一秒鐘執(zhí)行一次琼锋。
  • java線程池種類

  1. newCachedThreadPool創(chuàng)建一個可緩存線程池放闺,如果線程池長度超過處理需要,可靈活回收空閑線程缕坎,若無可回收怖侦,則新建線程。

  2. newFixedThreadPool 創(chuàng)建一個定長線程池谜叹,可控制線程最大并發(fā)數(shù)匾寝,超出的線程會在隊列中等待。

  3. newScheduledThreadPool 創(chuàng)建一個定長線程池荷腊,支持定時及周期性任務(wù)執(zhí)行艳悔。

  4. newSingleThreadExecutor 創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務(wù)女仰,保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行

不過在工作中很钓,如果你使用Executors的方式去創(chuàng)建線程,可能會失業(yè)的董栽,原因直接貼上阿里開發(fā)手冊的說明。

image.png

  • 正確創(chuàng)建線程池的姿勢

image.png

  • 線程池創(chuàng)建線程執(zhí)行和拒絕策略如下:

當(dāng)一個任務(wù)通過 execute(Runnable) 方法欲添加到線程池時企孩,線程池采用的策略如下(即添加任務(wù)的策略):

如果此時線程池中的數(shù)量小于 corePoolSize 锭碳,即使線程池中的線程都處于空閑狀態(tài),也要創(chuàng)建新的線程來處理被添加的任務(wù)勿璃。

如果此時線程池中的數(shù)量等于 corePoolSize 擒抛,但是緩沖隊列 workQueue 未滿推汽,那么任務(wù)被放入緩沖隊列。

如果此時線程池中的數(shù)量大于 corePoolSize 歧沪,緩沖隊列 workQueue 滿歹撒,并且線程池中的數(shù)量小于maximumPoolSize ,建新的線程來處理被添加的任務(wù)诊胞。

如果此時線程池中的數(shù)量大于 corePoolSize 暖夭,緩沖隊列 workQueue 滿,并且線程池中的數(shù)量等于maximumPoolSize 撵孤,那么通過 handler 所指定的策略來處理此任務(wù)迈着。

  • 使用有界隊列時,如果任務(wù)隊列滿了則執(zhí)行拒絕策略(第二個用的多些)

  1. ThreadPoolExecutor.AbortPolicy 丟棄任務(wù)邪码,并拋出 RejectedExecutionException 異常裕菠。備注:此種方法必須要捕獲線程池添加任務(wù)代碼,不然添加異常就不會走shutdown關(guān)閉線程池代碼闭专,會導(dǎo)致線程池一直處于未關(guān)閉狀態(tài)奴潘。

  2. ThreadPoolExecutor.CallerRunsPolicy:該任務(wù)被線程池拒絕,由調(diào)用 execute方法的線程執(zhí)行該任務(wù)影钉。備注:其實就是主線程去執(zhí)行被線程池拒絕的任務(wù)画髓。

  3. ThreadPoolExecutor.DiscardOldestPolicy : 拋棄隊列最前面的任務(wù),然后重新嘗試執(zhí)行任務(wù)斧拍。備注:就是移除隊列中第一個添加進去的任務(wù)雀扶,把后來的任務(wù)加在隊列最后。

  4. ThreadPoolExecutor.DiscardPolicy肆汹,丟棄任務(wù)愚墓,不過也不拋出異常。備注:直接丟棄隊列滿了之后添加進來的任務(wù)昂勉。

  • 如何優(yōu)雅的關(guān)閉線程池:

線程池有2種關(guān)閉方法:

  1. shutdown():線程池拒接收新提交的任務(wù)浪册,同時等待線程池里的任務(wù)執(zhí)行完畢后關(guān)閉線程池。
  2. shutdownNow() :線程池拒接收新提交的任務(wù)岗照,同時立馬關(guān)閉線程池村象,線程池里的任務(wù)不再執(zhí)行,并能獲取未被執(zhí)行的任務(wù)攒至。

關(guān)閉線程池的時候厚者,線程池中的線程有4種狀態(tài):

  1. 處于空閑狀態(tài) — shutdown: 正常退出,shutdownNow: 正常退出
  2. 處于正在處理任務(wù)的狀態(tài) — shutdown: 任務(wù)處理完成正常退出迫吐,shutdownNow: 任務(wù)處理完成正常退出
  3. 處于正在從任務(wù)隊列讀取任務(wù)的狀態(tài)— shutdown: 繼續(xù)讀取并任務(wù)執(zhí)行库菲,直到所有任務(wù)全部執(zhí)行完畢退出,shutdownNow: 停止讀取并退出
  4. 處于阻塞狀態(tài)— shutdown: 線程繼續(xù)阻塞志膀,并等待阻塞結(jié)束繼續(xù)執(zhí)行任務(wù)熙宇,shutdownNow: 拋出InterruptedException異常

所以鳖擒,我們該如何正確關(guān)閉線程池

  • 當(dāng)調(diào)用shutdownNow()方法時,如果確定可能會有阻塞的任務(wù)存在烫止,一定要捕獲異常進行處理
  • 當(dāng)調(diào)用shutdown()方法時蒋荚,一定要確保任務(wù)里不會有永久阻塞等待的線程,否則線程池就關(guān)閉不了馆蠕,不行的話可以等待一段時間后調(diào)用shutdownNow()方法

如果要在線程池任務(wù)執(zhí)行完關(guān)閉之后才能執(zhí)行其他的主邏輯期升,那么我們就必須要等到線程池任務(wù)全部執(zhí)行結(jié)束,需要注意的是荆几,不管是shutdown還是shutdownNow方法吓妆,其實都是發(fā)起線程關(guān)閉,但是線程池此時并不一定完全關(guān)閉了吨铸,因為可能有線程還在執(zhí)行任務(wù)或者隊列里還有任務(wù)等待執(zhí)行行拢,所以我們需要通過pool.awaitTermination(2, TimeUnit.SECONDS)方法去判斷線程池是否真的完全關(guān)閉了

  • pool.awaitTermination(2, TimeUnit.SECONDS)
    第一個參數(shù)為時間,第二個參數(shù)為單位
    這是一個阻塞方法诞吱,返回true和false舟奠,線程池關(guān)閉為true,未關(guān)閉為false
    在指定時間內(nèi)房维,如果線程池關(guān)閉了沼瘫,此方法結(jié)束阻塞,返回true咙俩,繼續(xù)執(zhí)行之后的代碼
    在指定時間內(nèi)耿戚,如果線程池未關(guān)閉,會一直阻塞阿趁,直到指定時間到了返回false膜蛔。
    注意:此方法為阻塞方法,如果任務(wù)沒有結(jié)束脖阵,子線程會阻塞于此皂股,主線程也會被阻塞等待,當(dāng)需要線程池的任務(wù)全部結(jié)束才能執(zhí)行主線程時命黔,可以用此方法呜呐,輸入一個時間比較長的參數(shù)
    所以,一般shutdown()或者shutdownNow()方法要配合awaitTermination()方法一起使用悍募。

其實關(guān)鍵就在于是否有阻塞的任務(wù)蘑辑,下面是一種參考處理方法

threadPool.shutdown(); // Disable new tasks from being submitted
        // 設(shè)定最大重試次數(shù)
        try {
            // 等待 60 s
            if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
                // 調(diào)用 shutdownNow 取消正在執(zhí)行的任務(wù)
                threadPool.shutdownNow();
                // 再次等待 60 s,如果還未結(jié)束坠宴,可以再次嘗試以躯,或者直接放棄
                if (!threadPool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("線程池任務(wù)未正常執(zhí)行結(jié)束");
            }
        } catch (InterruptedException ie) {
            // 重新調(diào)用 shutdownNow
            threadPool.shutdownNow();
        }

線程關(guān)閉的參考資料:
https://www.cnblogs.com/qingquanzi/p/9018627.html
https://cloud.tencent.com/developer/article/1523115
https://blog.csdn.net/chun_hua_xue_yue/article/details/96475075

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子忧设,更是在濱河造成了極大的恐慌,老刑警劉巖颠通,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件址晕,死亡現(xiàn)場離奇詭異,居然都是意外死亡顿锰,警方通過查閱死者的電腦和手機谨垃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來硼控,“玉大人刘陶,你說我怎么就攤上這事±魏常” “怎么了匙隔?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長熏版。 經(jīng)常有香客問我纷责,道長,這世上最難降的妖魔是什么撼短? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任再膳,我火速辦了婚禮,結(jié)果婚禮上曲横,老公的妹妹穿的比我還像新娘喂柒。我一直安慰自己,他們只是感情好禾嫉,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布灾杰。 她就那樣靜靜地躺著,像睡著了一般夭织。 火紅的嫁衣襯著肌膚如雪吭露。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天尊惰,我揣著相機與錄音讲竿,去河邊找鬼。 笑死弄屡,一個胖子當(dāng)著我的面吹牛题禀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播膀捷,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼迈嘹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起秀仲,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤融痛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后神僵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雁刷,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年保礼,在試婚紗的時候發(fā)現(xiàn)自己被綠了沛励。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡炮障,死狀恐怖目派,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胁赢,我是刑警寧澤企蹭,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站徘键,受9級特大地震影響练对,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吹害,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一螟凭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧它呀,春花似錦螺男、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谓媒,卻和暖如春淆院,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背句惯。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工土辩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抢野。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓拷淘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親指孤。 傳聞我的和親對象是個殘疾皇子启涯,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

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