成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

線程池中線程是如何保活和回收的

開發
面試時經常被問的一個問題,線程池中線程是如何保活的?現在我們就一起看一下線程池線程的保活策略。

面試時經常被問的一個問題,線程池中線程是如何保活的?

這個問題對于看過線程池源碼的同學應該已經知道答案了,沒有看過源碼的也不要慌,現在我們就一起看一下線程池線程的保活策略。

一、線程池中在哪執行任務

首先進入ThreadPoolExecutor的execute方法。

  • 首先檢查當前工作線程數量,workerCountOf(c) 是否小于核心線程數量corePoolSize,如果小于就創建一個新線程addWorker()執行這個任務。
  • 如果線程池在運行且任務加入隊列成功,但是當前工作線程數量為0,也會創建一個新線程addWorker()。
  • 如果任務不能被加入任務隊列(workQueue.offer(command)返回false), 也會創建一個新線程addWorker()。

在execute方法內部有三處調用addWorker()方法的位置,進入到addWorker() 方法中,可以看到有這樣一行代碼new Worker(firstTask) 。

而 Worker類又實現了 Runnable,所以線程池中的線程也就是Worker,而執行就在run()方法內部,我們只需要找到Worker類中的run方法即可。

Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }

run 方法內部調用了 runWorker,秘密就在runWorker方法內部。

所以線程池中線程最終就在runWorker方法中執行的。

二、getTask 獲取任務方法

在上面ThreadPoolExecutor的execute方法中,有一步是往阻塞隊列中放入任務(workQueue.offer(command))。

上面我們找到了線程池中線程執行任務的地方,那么我們看看是從哪讀取的任務?

runWorker方法中有一行代碼task = getTask(),此處就是從阻塞隊列中獲取任務的代碼,讓我們看一下 getTask() 的內部實現。

核心代碼就是

Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();

根據timed 的狀態判斷,當工作線程數量大于核心線程數量時調用poll方法獲取任務,當工作線程數量小于和核心線程數量時調用take方法。

對于阻塞隊列的介紹如下:

  • poll 方法如果隊列不為空,返回頭部元素。如果隊列為空會將線程阻塞在此處,阻塞時間是keepAliveTime。當時間到了獲取不到任務時返回null。
  • take方法如果隊列不為空返回頭部元素。如果隊列為空會將線程阻塞在此處,直到隊列中有元素可供使用。

對于非核心線程,當線程池中的線程數量超過核心線程數量且空閑時間超過keepAliveTime時,非核心線程會被回收。

通過這種方式,線程在沒有任務時就阻塞在隊列上,從而實現保活。

上面我們知道了非核心線程的保活策略,那么對于核心線程又是如何保活的呢?

三、核心線程如何實現的保活

在線程池中核心線程默認是不會被回收的。

不過我們可以通過設置allowCoreThreadTimeOut來實現,getTask方法中timed的校驗。

boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

所以當allowCoreThreadTimeOut 設置為true時,核心線程在沒有任務可以執行時會使用take方法進行阻塞,直到獲取到任務位置,而不是因為沒有任務就被銷毀,從而實現的線程保活。

任務執行的過程是無法保證不出問題的,不管是核心線程還是非核心線程,當線程中出現異常之后,線程池是如何處理的呢?

四、線程異常之后如何保活

繼續回到runWorker方法中,其中task.run()是真正執行任務的地方,當此處發生異常之后,有try catch。

所以當任務執行異常之后,會依次執三個finally塊中的代碼。

再看processWorkerExit() 方法之前,我們先看一個參數completedAbruptly。

completedAbruptly 代表是否是異常退出的,默認是true代表異常退出。

在runWorker方法中,如果線程任務是正常執行完成的,會在最后修改該值。

由于我們是異常線程,所以代碼肯定不會走到這,直接走到finally中的processWorkerExit方法。

在processWorkerExit方法中,它會根據completedAbruptly的值來調整線程池中的工作線程數量,從工作線程集合中移除該線程,并根據線程池的狀態和工作線程數量決定是否需要添加新線程。

!completedAbruptly 判斷工作線程是不是異常退出的,如果不是異常退出的計算最小線程數量。

如果允許核心線程回收allowCoreThreadTimeOut=true,min為0。

如果min為0 且工作隊列不為空! workQueue.isEmpty(),min為1。

如果當前工作線程workerCountOf(c)大于等于這個最小的線程數量min,直接返回。

如果小于這個最小的工作線程數量min,調用addWorker。

此處addWorker 的觸發條件就是當線程池的狀態小于STOP 也就是線程池還在運行runStateLessThan(c, STOP)時且不滿足上述不需要添加新線程的判斷。

當上述條件滿足的時候,則調用addWorker(null,false)添加一個新的工作線程,因為傳入的參數Runnable為null,所以這個新線程會從任務隊列中繼續讀取任務來執行。

最后總結一下,當線程異常之后,按照正常情況來說線程就直接消失了,但是通過processWorkerExit方法的補救,增加了一個新的線程,保證線程池的運行。

五、總結

線程池中的線程分為核心線程與非核心線程。

核心線程默認不回收,可以通過設置allowCoreThreadTimeOut為true 來回收。

非核心線程在獲取任務為空且空閑時間超過一定時間之后進行回收。

線程池的保活策略通過阻塞隊列的阻塞特性實現,poll 方法實現可以指定超時時間的阻塞,take 方法實現阻塞直到獲取到任務。

當線程異常之后,通過新增線程的方式實現線程的補救,保證線程池的運行。

責任編輯:趙寧寧 來源: 醉魚Java
相關推薦

2024-06-13 09:30:33

Java線程池線程

2023-02-02 08:56:25

線程池線程submit

2024-08-29 08:54:35

2024-04-02 09:53:08

線程池線程堆棧

2020-02-26 15:12:43

線程池增長回收

2025-02-05 14:28:19

2021-11-29 10:55:11

線程池Java面試

2011-06-01 11:23:09

Android 線程

2021-06-17 06:57:10

SpringBoot線程池設置

2019-09-26 10:19:27

設計電腦Java

2022-10-12 09:01:52

Linux內核線程

2012-01-16 09:00:56

線程

2024-04-08 10:09:37

TTLJava框架

2023-10-26 08:25:35

Java線程周期

2021-06-24 08:02:35

線程池Java代碼

2024-08-30 08:23:06

2020-10-12 08:32:34

瀏覽器進程線程

2024-05-20 13:13:01

線程安全Java

2022-10-24 08:03:04

MySQL數據庫

2022-09-06 08:25:13

線程異步任務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久国产精品99 | 亚洲午夜久久久 | 日韩成人av在线播放 | 国产亚洲精品久久午夜玫瑰园 | 日韩无| 激情一区二区三区 | 国产精品色综合 | 一区在线视频 | 欧美午夜精品 | 欧美在线视频网 | 国产日韩精品一区 | 日韩电影免费在线观看中文字幕 | 日韩在线一区二区三区 | 欧美日韩国产在线观看 | 欧美日韩一区二区在线观看 | 日韩一区二区在线播放 | 青青伊人久久 | 日韩精品久久一区二区三区 | 国产精品久久久久久中文字 | 久久免费国产 | 午夜视频在线 | 91av在线免费| 欧美成人激情 | 二区av| 五月激情婷婷网 | 日韩欧美电影在线 | 久草福利| 人干人人 | 国产成人一区二区三区电影 | 国产激情视频在线观看 | 国产第1页 | www国产亚洲精品久久网站 | 亚洲免费视频播放 | 国产精品1区2区 | 久久久久久女 | 狠狠操电影 | 欧美八区| 欧美黑人体内she精在线观看 | 免费av直接看 | 免费黄色a视频 | 嫩草最新网址 |