線程池介紹

概述

多線程并行處理任務(wù)是壓榨 CPU 的最有效方式,而線程在執(zhí)行完任務(wù)后如果直接銷毀,這個(gè)是對(duì)資源的浪費(fèi),于是就有了池化的概念;
創(chuàng)建一個(gè)包含多個(gè)線程的池,當(dāng)需要用到線程是是直接使用池中的線程,而不是單獨(dú)在創(chuàng)建一個(gè)線程,從而避免了線程重復(fù)創(chuàng)建和銷毀的開(kāi)銷,提高了資源的利用率;
線程池是通過(guò)生成者消費(fèi)者模式構(gòu)建的,當(dāng)我們使用線程池的 submit 方法提交任務(wù)時(shí),就是擔(dān)任了生產(chǎn)者的角色來(lái)提交任務(wù),當(dāng)線程池中的線程執(zhí)行隊(duì)列中的任務(wù)時(shí)就是擔(dān)任類消費(fèi)者的模式消費(fèi)任務(wù);
在 JDK 中提供了 ThreadPoolExecutor 類用來(lái)實(shí)現(xiàn)線程池。

線程池參數(shù)介紹

首先給出創(chuàng)建線程池類的構(gòu)造方法:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

可以看到構(gòu)造方法中入?yún)⒂?個(gè),接下來(lái)分別介紹;

corePoolSize

線程池的核心線程數(shù);所謂核心線程數(shù)就是線程池通常情況下維護(hù)的最大線程數(shù),而通常情況指的是當(dāng) workQueue 未滿,也就是只要任務(wù)隊(duì)列未滿,線程池中最大線程數(shù)就是核心線程數(shù);具體的執(zhí)行過(guò)程是,當(dāng)線程池中線程數(shù)未達(dá)到 corePoolSize 時(shí),一個(gè)任務(wù)被提交后線程池會(huì)先創(chuàng)建一個(gè)線程去執(zhí)行該任務(wù),當(dāng)線程池中線程數(shù)達(dá)到了 corePoolSize 后,一個(gè)任務(wù)被提交后會(huì)放入到任務(wù)隊(duì)列中,只要隊(duì)列未滿,線程池中最大線程數(shù)就是 corePoolSize;

maximumPoolSize

最大線程數(shù);這個(gè)就是真正意義上的線程池中所能創(chuàng)建線程的最大值了,只有當(dāng)任務(wù)隊(duì)列已滿,有新任務(wù)被提交后線程池才會(huì)創(chuàng)建新線程來(lái)執(zhí)行任務(wù),這個(gè)時(shí)候線程池的線程數(shù)量會(huì)超過(guò) corePoolSize 的大小,當(dāng)線程池的線程數(shù)達(dá)到 maximumPoolSize 時(shí),線程池會(huì)執(zhí)行 handler 里的拒絕策略;

keepAliveTime & unit

線程的保留時(shí)間和時(shí)間單位;這個(gè)針對(duì)的是非核心線程而言的,因?yàn)楫?dāng)隊(duì)列滿了之后才會(huì)創(chuàng)建非核心線程之外的額外線程來(lái)處理任務(wù),但是當(dāng)任務(wù)處理完成隊(duì)列又有容量的時(shí)候,說(shuō)明線程池是處在閑置的狀態(tài),而多余的線程就是一種資源的浪費(fèi),所以線程池會(huì)將多余的線程移除并銷毀,而這個(gè)保留時(shí)間就是指當(dāng)線程池處于閑置狀態(tài)時(shí),多余的線程在池中最大的保留時(shí)間,超過(guò)這個(gè)時(shí)間后,多余的線程就會(huì)被銷毀;

threadFactory

線程池中創(chuàng)建線程的工廠;這個(gè)其實(shí)沒(méi)啥好介紹的,就是一個(gè)線程池創(chuàng)建的工廠,可以自定義一個(gè)線程工廠,給線程設(shè)置自定義的名稱等,方便查日志及定位問(wèn)題;

workQueue

線程池中用來(lái)保存提交任務(wù)的阻塞隊(duì)列;上文中提到線程池是基于生產(chǎn)者消費(fèi)者模型構(gòu)建的,因此就需要用到阻塞隊(duì)列來(lái)存儲(chǔ)對(duì)應(yīng)的任務(wù),生產(chǎn)者把任務(wù)提交到隊(duì)列,消費(fèi)者從隊(duì)列中獲取任務(wù)進(jìn)行執(zhí)行;在 JDK 中提供了幾種阻塞隊(duì)列;
ArrayBlockingQueue:使用數(shù)組實(shí)現(xiàn)的阻塞隊(duì)列因此構(gòu)造時(shí)必須要傳隊(duì)列的大小,因此是一個(gè)有界的隊(duì)列;
LinkedBlockingQueue:使用鏈表實(shí)現(xiàn)的阻塞隊(duì)列,如果指定大小則容量以指定大小為準(zhǔn)否則取 int 的最大值;
SynchronousQueue:內(nèi)部只能包含一個(gè)元素的同步隊(duì)列,能保證兩個(gè)線程同步執(zhí)行;
PriorityBlockingQueue : 使用平衡二叉樹(shù)堆實(shí)現(xiàn)的優(yōu)先級(jí)隊(duì)列無(wú)界阻塞隊(duì)列,每次都返回優(yōu)先級(jí)最低或最高的元素;

handler

線程池中的拒絕策略;這個(gè)拒絕策略其實(shí)是一個(gè)兜底的方案,因?yàn)榫€程池是有界的,有最大線程數(shù)的限制也有最大隊(duì)列容量的限制,當(dāng)超過(guò)線程池本身的限制時(shí),我們提交的任務(wù)線程池其實(shí)是沒(méi)有能力再去處理的,這個(gè)時(shí)候就需要一個(gè)兜底的方案去做這件事情,而拒絕策略就是用來(lái)做這個(gè)的;在 JDK 中為我們提供了幾種拒絕策略,我們也可以去自己實(shí)現(xiàn)拒絕策略,下面介紹一下JDK 提供的拒絕策略;
AbortPolicy(默認(rèn)):丟棄當(dāng)前任務(wù)并拋出 RejectedExecutionException 異常;
DiscardPolicy:丟棄當(dāng)前任務(wù),不拋出異常;
DiscardOldestPolicy:丟棄隊(duì)列中最舊的任務(wù),然后將當(dāng)前任務(wù)加入隊(duì)列;
CallerRunsPolicy:使用用調(diào)用者的線程繼續(xù)執(zhí)行任務(wù);

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容