線程池的基本結(jié)構(gòu)以及實(shí)現(xiàn)原理

線程池的基本結(jié)構(gòu)

線程池主要線程和一個(gè)阻塞隊(duì)列組成。

線程池的執(zhí)行流程

大體流程

當(dāng)一個(gè)任務(wù)提交到線程池時(shí)
第一步 會(huì)先判斷線程池里的核心線程是否都在執(zhí)行任務(wù);如果有可用線程并且當(dāng)前線程池中的核心線程數(shù)還小于 corePoolSize則創(chuàng)建線程使用,否則就進(jìn)入下一個(gè)流程;
第二步 線程池判斷工作隊(duì)列是否已滿,如果工作隊(duì)列沒(méi)有滿,則將新提交的任務(wù)存儲(chǔ)在這個(gè)工作隊(duì)列里。如果工作隊(duì)列滿了,則進(jìn)入下個(gè)流程;
第三步 判斷線程池里的線程是否都處于工作狀態(tài),如果沒(méi)有,查看一下當(dāng)前線程數(shù)是否到達(dá)maximumPoolSize,如果還未到達(dá),就繼續(xù)創(chuàng)建線程。如果已經(jīng)到達(dá)了,就交給RejectedExecutionHandler來(lái)決定怎么處理這個(gè)任務(wù)。

execute()方法

  public void execute(Runnable command) {
          if (command == null)
              throw new NullPointerException();
        //如果線程數(shù)大于等于基本線程數(shù)或者線程創(chuàng)建失敗,將任務(wù)加入隊(duì)列
          if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
           //線程池處于運(yùn)行狀態(tài)并且加入隊(duì)列成功
              if (runState == RUNNING && workQueue.offer(command)) {
                  if (runState != RUNNING || poolSize == 0)
                      ensureQueuedTaskHandled(command);
              }
           //線程池不處于運(yùn)行狀態(tài)或者加入隊(duì)列失敗,則創(chuàng)建線程(創(chuàng)建的是非核心線程)
              else if (!addIfUnderMaximumPoolSize(command))
              //創(chuàng)建線程失敗,則采取阻塞處理的方式
                 reject(command); // is shutdown or saturated
         }
     }

addIfUnderCorePoolSize()

private boolean addIfUnderCorePoolSize(Runnable firstTask) {
        Thread t = null;
        final ReentrantLock mainLock = this.mainLock;
        //阻塞鎖
        mainLock.lock();
        try {
            if (poolSize < corePoolSize && runState == RUNNING)
                t = addThread(firstTask);
        } finally {
            mainLock.unlock();
        }
        if (t == null)
            return false;
        //啟動(dòng)線程
        t.start();
        return true;
    }

addThread()方法

private Thread addThread(Runnable firstTask) {
        Worker w = new Worker(firstTask);
        Thread t = threadFactory.newThread(w);
        if (t != null) {
            w.thread = t;
            workers.add(w);
            int nt = ++poolSize;
            if (nt > largestPoolSize)
                largestPoolSize = nt;
        }
        return t;
    }
最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

  • JAVA線程池的分析和使用 引言 合理利用線程池能帶來(lái)三個(gè)好處: 降低資源消耗。通過(guò)重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)...
    胖瘦饅頭閱讀 388評(píng)論 0 0
  • Java中的線程池是運(yùn)用場(chǎng)景最多的并發(fā)框架,幾乎所有需要異步或并發(fā)執(zhí)行任務(wù)的程序都可以使用線程池。在開(kāi)發(fā)過(guò)程中,合...
    CodeKing2017閱讀 1,056評(píng)論 0 0
  • 為什么要使用線程池 在web開(kāi)發(fā)中,服務(wù)器需要接受并處理請(qǐng)求,所以會(huì)為一個(gè)請(qǐng)求來(lái)分配一個(gè)線程來(lái)進(jìn)行處理。如果每次請(qǐng)...
    先生zeng閱讀 383評(píng)論 0 7
  • 憂郁的眼神 這歡鬧的氣氛 只你一人不開(kāi)心 低頭沉思 倚著門(mén)框 孤獨(dú)的背影 落寞的神情 我想要你開(kāi)心 該怎么讓你開(kāi)心...
    夕曦夕曦閱讀 270評(píng)論 2 2
  • 還是寒冬臘月的時(shí)候,老房子旁邊石堆上的老酸梅樹(shù)就首先迸發(fā)出粉紅色的花蕾。沒(méi)過(guò)兩天,河岸山坡所有的野生梅花都盛...
    山神山神閱讀 320評(píng)論 3 3

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