阿里面試必問之線程池(上)

前言

由于線程池涉及的知識(shí)點(diǎn)比較多,會(huì)以上中下三篇文章來敘述;
當(dāng)我們面試時(shí),如果遇到了面試官讓你說一下線程池,我們可以先講一下線程池的核心思想:
1.復(fù)用線程,降低線程創(chuàng)建與銷毀代價(jià)。
2.提升處理速度,避免了等待線程創(chuàng)建的時(shí)間。
3.池化,方便統(tǒng)一管理與監(jiān)控。

總體實(shí)現(xiàn)

ThreadPoolExecutor是線程池的核心類,主要負(fù)責(zé)線程管理和任務(wù)分發(fā)


線程池1.png

線程池本身就是一個(gè)生產(chǎn)-消費(fèi)者模型,將任務(wù)生產(chǎn)與任務(wù)消費(fèi)完全解耦,達(dá)到緩沖目的。

任務(wù)管理

當(dāng)用戶提交一個(gè)任務(wù)后,接下來這個(gè)任務(wù)將如何執(zhí)行:
1.直接拿到核心線程進(jìn)行任務(wù)執(zhí)行
2.進(jìn)入到緩沖隊(duì)列,等待非核心線程
3.拒絕
源碼如下:

   public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
//直接拿到核心線程進(jìn)行任務(wù)執(zhí)行
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
//進(jìn)入到緩沖隊(duì)列,等待非核心線程
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
//拒絕
        else if (!addWorker(command, false))
            reject(command);
    }

源碼邏輯:
1.如果workerCount < corePoolSize 則啟動(dòng)新線程
2.如果workerCount >= corePoolSize 則加入緩沖隊(duì)列,等待執(zhí)行
3.如果 workerCount < maximumPoolSize ,并且緩沖隊(duì)列已滿,則啟動(dòng)新線程
4.workerCount > maximumPoolSize 執(zhí)行拒絕策略

任務(wù)緩沖

線程池本身是個(gè)生產(chǎn)消費(fèi)者模式,用戶將任務(wù)生產(chǎn)到任務(wù)隊(duì)列,然后線程從任務(wù)隊(duì)列拿任務(wù)。線程池的隊(duì)列是BlockingQueue,但是線程池可以通過不同的Queue實(shí)現(xiàn)不一樣的存儲(chǔ)策略。
ArrayBlockingQueue:規(guī)定大小的阻塞隊(duì)列,元素先進(jìn)先出,要指定容量。
LinkedBlockingQueue:默認(rèn)大小為Integer.MAX_VALUE,要注意容量。
PriorityBlockingQueue:自定義實(shí)現(xiàn)compareTo()方法來置頂元素排序規(guī)則,不能保證同優(yōu)先級(jí)元素的順序。
SynchronousQueue:每一個(gè)put操作必須等待take操作,否則不能添加元素,如果有空閑線程則會(huì)重復(fù)使用,線程空閑了60s后會(huì)被自動(dòng)回收。

任務(wù)拒絕

線程池有一個(gè)最大的容量,當(dāng)線程池的任務(wù)緩存隊(duì)列已滿,并且線程池中的線程數(shù)目達(dá)到maximumPoolSize時(shí),就需要拒絕掉該任務(wù),采取任務(wù)拒絕策略,保護(hù)線程池。

下篇會(huì)講一下線程池中的worker是如何執(zhí)行任務(wù)的,線程是如何復(fù)用的。

?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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