線程池

此文參考博客編寫.

1.什么是線程池

線程池就是若干個(gè)線程的集合,這些線程被池化了,能夠執(zhí)行多個(gè)任務(wù).而并非只為執(zhí)行一次任務(wù)而創(chuàng)建,也并非執(zhí)行完任務(wù)就銷毀.

2.線程池的實(shí)現(xiàn)原理

上述提到的若干個(gè)線程,我們稱之為工作線程. 一個(gè)線程池中通常有個(gè)定量的阻塞隊(duì)列queue與其配合使用,當(dāng)外部向一個(gè)線程池提交一個(gè)任務(wù)時(shí),線程池會將這個(gè)任務(wù)放置到queue中,而線程池中的工作線程會不斷向queue中取出任務(wù)執(zhí)行.執(zhí)行完之后如果發(fā)現(xiàn)queue不為空,則繼續(xù)取,如果queue已經(jīng)為空, 工作線程們進(jìn)入waiting狀態(tài). 待queue再次不會空,這些線程會被喚醒.從而進(jìn)行下一次任務(wù)的執(zhí)行.大概原理就是這樣

3.線程池如何使用

看看JDK為我們提供的ThreadPoolExecutor.
我們可通過ThreadPoolExecutor來創(chuàng)建一個(gè)線程池.再調(diào)用其execute方法,傳入我們的任務(wù)Runable對象即可.

  1. 參數(shù)
  • int corePoolSize
    基本工作線程數(shù)量
  • int maximumPoolSize
    最大工作線程數(shù)量
  • long keepAliveTime
    默認(rèn)全部工作線程除去基本工作線程的線程空閑時(shí)間.也可設(shè)置為所有線程的空閑時(shí)間. 一旦空閑時(shí)間超過了設(shè)定值,工作線程將被銷毀.
  • TimeUnit unit
    描述上個(gè)參數(shù)的單位.
  • BlockingQueue<Runnable> workQueue
    存放任務(wù)的阻塞隊(duì)列
  • ThreadFactory threadFactory
    作用是根據(jù)任務(wù)Runable對象來生產(chǎn)工作線程中的線程. 比如可以對生成的線程設(shè)置名字等屬性.
  • RejectedExecutionHandler handler
    如果任務(wù)Runable對象被拒絕了,將會調(diào)用
    handler.rejectedExecution(Runnable r, ThreadPoolExecutor executor)
    你可以拋出異常或者選擇死亡
  1. 工作流程


    流程圖

    看完上述對參數(shù)比較口語化的描述.我們用他們來模擬一個(gè)ThreadPoolExecutor當(dāng)執(zhí)行execute方法是怎么干的
    首先我們需要用一個(gè)Set<Worker>表示當(dāng)前我們持有的工作線程.

  • 如果set的size比corePoolSize小,那就證明還沒有達(dá)到基本數(shù)量. 這個(gè)時(shí)候新建一個(gè)工作線程Worker來執(zhí)行Runable對象并將Worker放入set.
  • 如果set的size已經(jīng)比corePoolSize大.那這個(gè)時(shí)候把Runable對象放入構(gòu)造函數(shù)傳進(jìn)來的BlockingQueue. 注意.此時(shí)調(diào)用的不是put方法,也不是add方法,是offer方法. offer方法特點(diǎn)就是如果隊(duì)列已滿就返回false.不等待也不拋異常,很老實(shí).. 如果放入成功,后續(xù)就會有工作線程來取走這個(gè)Runable對象.
放入Queue
  • 如果放入失敗了. 那么判斷set的size是不是比maximumPoolSize 小. 如果小,新建一個(gè)工作線程Worker來執(zhí)行Runable對象.并將Worker放入set.
  • 如果大,這個(gè)時(shí)候拒絕執(zhí)行Runable對象. 調(diào)用構(gòu)造函數(shù)傳入的RejectedExecutionHandler.rejectedExecution();
  1. ThreadPoolExecutor狀態(tài)
狀態(tài)流轉(zhuǎn)圖
  • RUNNING
    初始狀態(tài),接受新任務(wù)并且處理已經(jīng)在隊(duì)列中的任務(wù)。
  • SHUTDOWN
    不接受新任務(wù),但處理隊(duì)列中的任務(wù)。
  • STOP
    不接受新任務(wù),不處理排隊(duì)的任務(wù),并中斷正在進(jìn)行的任務(wù)。
  • TIDYING
    所有任務(wù)已終止,workerCount為零,線程轉(zhuǎn)換到狀態(tài)TIDYING,這時(shí)回調(diào)terminate()方法。
  • TERMINATED
    終態(tài),terminated()執(zhí)行完成。

4.線程池的意義

  • 降低資源消耗
    通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀的消耗
  • 提高響應(yīng)速度
    當(dāng)一個(gè)任務(wù)到達(dá)的時(shí)候,不必等待線程創(chuàng)建的時(shí)間就可以馬上執(zhí)行.
  • 提高線程的可管理性
    線程是稀缺的資源,如果無限制地創(chuàng)建,會降低系統(tǒng)的穩(wěn)定性.使用線程可以進(jìn)行統(tǒng)一分配/調(diào)優(yōu)/監(jiān)控.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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