并發(fā)編程之:線程池(一)

大家好,我是小黑枣抱,一個在互聯(lián)網(wǎng)茍且偷生的農(nóng)民工。

池化

線程池是在計算機(jī)開發(fā)中常見的一種池化技術(shù)辆床,是為了提高資源的利用率佳晶,將一些資源重復(fù)利用,避免重復(fù)的構(gòu)建來提高效率讼载。類似字符串常量池轿秧,數(shù)據(jù)庫連接池,HttpClient連接池等咨堤,都是用的池化技術(shù)菇篡。

線程池

在沒有線程池概念之前,我們要使用線程必須先通過創(chuàng)建一個Thread類來完成線程的構(gòu)建一喘,并調(diào)用start()方法開啟驱还,在線程執(zhí)行完會將線程銷毀嗜暴,而線程資源是很寶貴的,創(chuàng)建和銷毀線程會造成資源的浪費议蟆。而線程池是將創(chuàng)建的線程存儲到一個池中闷沥,在需要使用時從池中去拿,使用完之后再講線程歸還到池中咐容,下一次接著使用舆逃。

舉個栗子,好比我們?nèi)ャy行辦理業(yè)務(wù)時戳粒,銀行會有窗口為客戶辦理業(yè)務(wù)路狮,如果沒有線程池,就好比每次來一個客戶蔚约,銀行都打開一個窗口奄妨,辦理完業(yè)務(wù)之后將窗口關(guān)閉,這樣確實很浪費時間炊琉,所以銀行會默認(rèn)開幾個窗口展蒂,比如三個,等客戶來辦理業(yè)務(wù)苔咪;一個客戶辦理完锰悼,下一個客戶可以繼續(xù)在這個窗口辦理。

image

核心線程數(shù)

在線程池初始化時团赏,會指定創(chuàng)建核心線程的數(shù)量箕般,有任務(wù)提交給線程池時,先判斷是否有空閑線程舔清,如果有空閑線程丝里,則直接使用,如果沒有則看當(dāng)前線程池中的數(shù)量是不是小于核心線程數(shù)体谒,如果是則創(chuàng)建新的線程杯聚,如果已經(jīng)到達(dá)核心線程數(shù),則需要做下一步操作抒痒。

等待隊列

下一步操作就是要進(jìn)入等待隊列幌绍,等待隊列好比是去銀行辦業(yè)務(wù)時沒有空閑窗口,需要坐在大廳的座椅上排隊故响;線程池也是一樣傀广,如果沒有核心線程,則需要將任務(wù)放入等待隊列彩届,等待有空閑線程再執(zhí)行伪冰。

最大線程數(shù)

那我們都知道銀行有時候人特別多的時候,會增加窗口樟蠕,一般是當(dāng)大廳的座椅坐滿人時贮聂,窗口都很緊張?zhí)幚聿贿^來靠柑,這是會增加窗口;線程池也是一樣寂汇,如果等待的任務(wù)已經(jīng)放滿了等待隊列病往,并且核心線程都在繁忙,這時會查看線程池中的線程數(shù)量是否到達(dá)最大線程數(shù)骄瓣,如果沒有則會創(chuàng)建新的線程來繼續(xù)處理。

image-20210903211946836

拒絕策略

那如果說耍攘,線程池中的線程已經(jīng)到達(dá)最大線程數(shù)并且都在繁忙榕栏,還有新的任務(wù)進(jìn)來,好比銀行已經(jīng)坐滿人了蕾各,窗口也都在忙扒磁,客戶都排到門口了,這時要是還有人要辦理式曲,應(yīng)該怎么處理呢妨托?銀行一般會讓這個人先回家,改天再來辦吝羞,或者如果是個大客戶兰伤,銀行可能會單獨帶去VIP辦公室辦理等等。線程池在這種情況下也有相應(yīng)的處理方式钧排,這種處理方式我們稱之為拒絕策略敦腔,如果會放任務(wù)在當(dāng)前線程執(zhí)行,或者直接將任務(wù)丟棄等等恨溜,在后面的章節(jié)中我會詳細(xì)給大家介紹符衔。

JDK中的線程池

在JDK中提供了相應(yīng)的API來創(chuàng)建線程池,這些API也是在我們最近講到過的JUC包中糟袁。

image-20210903212843343

Executor

首先判族,線程池需要具備能夠執(zhí)行任務(wù)的能力,這個任務(wù)通過一個線程來處理项戴。而這個執(zhí)行任務(wù)的能力通過Executor接口來約定形帮。

public interface Executor {
    void execute(Runnable command);
}

ExecutorService

在某些場景我們需要知道任務(wù)執(zhí)行完之后的結(jié)果,拿到返回值肯尺,而Runnable接口是沒有返回值的沃缘;以及一些可以關(guān)閉線程池中的線程,執(zhí)行線程中的任務(wù)的方法则吟,定義在ExecutorService接口中槐臀。

image-20210903221251283

ThreadPoolExecutor

ThreaPoolExecutor則是對ExecutorService的具體實現(xiàn)類,通過ThreaPoolExecutor類可以創(chuàng)建出一個線程池氓仲,我們先來看一下代碼水慨。

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    // 核心線程數(shù) corePoolSize
    3, 
    // 最大線程數(shù) maximumPoolSize
    5, 
    // 空閑線程保留存活的時間和時間單位
    10, TimeUnit.SECONDS, 
    // 等待隊列
    new ArrayBlockingQueue<>(3), 
    // 創(chuàng)建線程的工廠
    Executors.defaultThreadFactory(), 
    // 拒絕策略
    new ThreadPoolExecutor.AbortPolicy() 
);

從代碼我們可以看出得糜,創(chuàng)建一個線程池,需要指定我們上面說到的核心線程數(shù)晰洒,最大線程數(shù)朝抖,等待隊列,拒絕策略等谍珊,并且還要指定創(chuàng)建線程的工廠對象治宣。

當(dāng)然ThreadPoolExecutor也有其他的構(gòu)造方法,可以不顯式指定拒絕策略和工廠對象砌滞。

new ThreadPoolExecutor(3,5,10,TimeUnit.SECONDS,new ArrayBlockingQueue<>(3));
// 構(gòu)造方法
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    // 使用默認(rèn)的線程工廠和默認(rèn)的拒絕策略侮邀。
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler); 
}

7個線程池參數(shù)

  • corePoolSize:核心線程數(shù)
  • maximumPoolSize:最大線程數(shù)
  • keepAliveTime:空閑線程保持存活時間
  • unit:空閑線程保持存活時間單位
  • workQueue:等待隊列
  • threadFactory:線程創(chuàng)建工廠
  • RejectedExecutionHandler:拒絕策略

4種拒絕策略

這里我們說一下4中拒絕策略。接口RejectedExecutionHandler定義了拒絕策略贝润,所有的拒絕策略都需要實現(xiàn)該接口绊茧。

public interface RejectedExecutionHandler {
    void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

在ThreadPoolExecutor類中定義了4個拒絕策略的具體實現(xiàn)。

  • AbortPolicy:拒絕處理打掘,拋出異常
  • CallerRunsPolicy:由創(chuàng)建該線程的線程(main)執(zhí)行
  • DiscardPolicy: 丟棄华畏,不拋出異常
  • DiscardOldestPolicy:和最早創(chuàng)建的線程進(jìn)行競爭,不拋出異常

可通過如下方式進(jìn)行拒絕策略的創(chuàng)建尊蚁。

// 拒絕處理亡笑,拋出異常
new ThreadPoolExecutor.AbortPolicy(); 
// 由創(chuàng)建該線程的線程(main)執(zhí)行
new ThreadPoolExecutor.CallerRunsPolicy();  
// 丟棄,不拋出異常
new ThreadPoolExecutor.DiscardPolicy(); 
// 和最早創(chuàng)建的線程進(jìn)行競爭枝誊,不拋出異常
new ThreadPoolExecutor.DiscardOldestPolicy(); 

4種線程池種類

那么具體我們在使用時應(yīng)該創(chuàng)建怎樣的線程池呢况芒?在JDK的Executors工具類為我們提供了4種線程池的創(chuàng)建方式。

// 只有一個線程
Executors.newSingleThreadExecutor(); 
// 固定線程數(shù)
Executors.newFixedThreadPool(5); 
// 可伸縮的
Executors.newCachedThreadPool(); 
// 可延遲執(zhí)行叶撒,使用優(yōu)先隊列DelayedWorkQueue
Executors.newScheduledThreadPool(3);

小結(jié)

好的绝骚,通過今天的內(nèi)容我們先對線程池的使用有一個初步的了解,下期內(nèi)容再跟大家深入解析一下線程池中的具體實現(xiàn)原理祠够。

本期內(nèi)容就到這里压汪,我們下期見。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末古瓤,一起剝皮案震驚了整個濱河市止剖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌落君,老刑警劉巖穿香,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異绎速,居然都是意外死亡皮获,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門纹冤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來洒宝,“玉大人购公,你說我怎么就攤上這事⊙愀瑁” “怎么了宏浩?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長靠瞎。 經(jīng)常有香客問我比庄,道長,這世上最難降的妖魔是什么乏盐? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任印蔗,我火速辦了婚禮,結(jié)果婚禮上丑勤,老公的妹妹穿的比我還像新娘。我一直安慰自己吧趣,他們只是感情好法竞,可當(dāng)我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著强挫,像睡著了一般岔霸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俯渤,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天呆细,我揣著相機(jī)與錄音,去河邊找鬼八匠。 笑死絮爷,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的梨树。 我是一名探鬼主播坑夯,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抡四!你這毒婦竟也來了柜蜈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤指巡,失蹤者是張志新(化名)和其女友劉穎淑履,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藻雪,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡秘噪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了阔涉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缆娃。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡捷绒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贯要,到底是詐尸還是另有隱情暖侨,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布崇渗,位于F島的核電站字逗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏宅广。R本人自食惡果不足惜葫掉,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望跟狱。 院中可真熱鬧俭厚,春花似錦、人聲如沸驶臊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽关翎。三九已至扛门,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纵寝,已是汗流浹背论寨。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留爽茴,地道東北人葬凳。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像闹啦,于是被迫代替她去往敵國和親沮明。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,472評論 2 348

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