java線程池學習(五) —— ThreadPoolExecutor源碼分析

通過前面的章節,我們學習了可以通過ThreadPoolExecutor來創建一個線程池。

那麼接下來我們分析一下ThreadPoolExecutor的源碼,看看它具體是如何工作的。

我們看一下使用execute(Runnable task)執行一個任務的時候,到底發生了什麼(代碼進過簡化):

先簡單描述一下當我們提交一個任務到線程池中後發生了什麼:


具體源碼如下:

    public void execute(Runnable task) {
        //取出當前線程池活躍的線程數。
        //ctl是一個原子類型的對象(final AtomicInteger ctl),用來保存當前線程池的線程數以及線程池的狀態。
        int c = ctl.get();
        //如果當前的活躍線程數小於核心線程數,即使現在有空閒線程,也創建一個新的線程,去執行這個任務
        if (workerCountOf(c) < corePoolSize) {
            //創建一個新的線程,去執行這個任務。
            if (addWorker(task, true))
                return;
            //如果執行到這一句說明任務沒有分配成功。
            //所以獲得當前線程池狀態值,爲後面的檢查做準備。
            c = ctl.get();
        }
        //如果大於核心線程數,檢查一下線程池是否還處於運行狀態,並嘗試把任務放入到blockingQueue任務隊列中。
        if (isRunning(c) && workQueue.offer(task)) {
            //這裏再次檢查一下線程池的狀態
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(task))
                //如果線程池不處於運行狀態的話,就把我們剛纔添加進任務隊列中的任務移出,並拒絕這個任務。
                reject(task);
            //檢查如果當前線程池中的線程數,如果爲0了,就爲線程池創建新線程(因爲有可能之前存活的線程在上一次檢查過後死亡了)
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //執行到這一句,說明隊列滿了。這時,如果當前線程池中的線程數還沒有超過最大線程數,就創建一個新的線程去執行這個任務,如果失敗就拒絕這個任務。
        else if (!addWorker(task, false))
            reject(task);
    }


以上就是ThreadPoolExecutor的基本執行流程。

發佈了40 篇原創文章 · 獲贊 32 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章