執行緒池任務增長過程分析

2021-10-10 03:03:37 字數 3840 閱讀 7462

//執行緒緩衝佇列

private static blockingqueuebqueue = new arrayblockingqueue(10);

// 核心執行緒數

private static final int size_core_pool = 5;

// 執行緒池維護執行緒的最大數量

private static final int size_max_pool = 9;

// 執行緒池維護執行緒所允許的空閒時間

private static final long alive_time = 2000;

//建立執行緒池

private static threadpoolexecutor pool = new threadpoolexecutor(size_core_pool, size_max_pool, alive_time, timeunit.milliseconds, bqueue, new threadpoolexecutor.callerrunspolicy());

static

threadpoolexecutor建構函式的引數意義不再多說,按照上面的引數配置,說明一下執行20個任務且每個任務執行時間1秒,執行緒池中的執行緒和佇列變化過程:

由於呼叫了prestartallcorethreads這個方法,執行緒池初始執行緒5個,新增前五個任務會分別占用乙個執行緒執行,第六個任務開始會被放到bqueue佇列中,佇列長度是10所以到第15個任務的時候核心執行緒被占用,佇列也滿了,第16個任務就會建立新的執行緒執行,這些任務不經過佇列排隊所以會在佇列中任務之前執行,直到第19個任務執行緒數達到size_max_pool大小數量9,不再建立執行緒,第20個任務就會按照阻塞策略執行,callerrunspolicy這個策略的意思就是在呼叫者執行緒中直接執行任務,也是不經過排隊,效果和前面建立執行緒執行一樣,隨著任務被執行,佇列中的任務被消費掉佇列的長度也會恢復到0,空閒執行緒空閒時間超過2秒執行緒會關閉,最後保留5個執行緒存活,用乙個main方法進行驗證:

public static void main(string args) throws interruptedexception  catch (interruptedexception e) 

system.out.println("完成第" + a + "個任務");

}});

}system.out.println("任務呼叫完成");

for (int i = 0; i < integer.max_value; i++)

}

執行結果:

執行緒池執行緒數:5,佇列長度0

呼叫第1個任務

執行緒池執行緒數:5,佇列長度1

呼叫第2個任務

執行緒池執行緒數:5,佇列長度1

呼叫第3個任務

執行緒池執行緒數:5,佇列長度1

呼叫第4個任務

執行緒池執行緒數:5,佇列長度0

呼叫第5個任務

執行緒池執行緒數:5,佇列長度1

呼叫第6個任務

執行緒池執行緒數:5,佇列長度1

呼叫第7個任務

執行緒池執行緒數:5,佇列長度2

呼叫第8個任務

執行緒池執行緒數:5,佇列長度3

呼叫第9個任務

執行緒池執行緒數:5,佇列長度4

呼叫第10個任務

執行緒池執行緒數:5,佇列長度5

呼叫第11個任務

執行緒池執行緒數:5,佇列長度6

呼叫第12個任務

執行緒池執行緒數:5,佇列長度7

呼叫第13個任務

執行緒池執行緒數:5,佇列長度8

呼叫第14個任務

執行緒池執行緒數:5,佇列長度9

呼叫第15個任務

執行緒池執行緒數:5,佇列長度10

呼叫第16個任務

執行緒池執行緒數:6,佇列長度10

呼叫第17個任務

執行緒池執行緒數:7,佇列長度10

呼叫第18個任務

執行緒池執行緒數:8,佇列長度10

呼叫第19個任務

執行緒池執行緒數:9,佇列長度10

呼叫第20個任務

完成第4個任務

完成第5個任務

完成第17個任務

完成第18個任務

完成第2個任務

完成第1個任務

完成第20個任務

完成第16個任務

完成第3個任務

任務呼叫完成

完成第19個任務

完成第6個任務

完成第12個任務

完成第9個任務

完成第14個任務

執行緒池執行緒數:9,佇列長度0

完成第8個任務

完成第10個任務

完成第11個任務

完成第7個任務

完成第13個任務

完成第15個任務

執行緒池執行緒數:9,佇列長度0

執行緒池執行緒數:9,佇列長度0

執行緒池執行緒數:5,佇列長度0

執行緒池執行緒數:5,佇列長度0

執行緒池執行緒數:5,佇列長度0

執行緒池執行緒數:5,佇列長度0

注釋掉靜態**塊中的pool.prestartallcorethreads();再執行執行緒數會從0開始,執行緒會在有任務執行的時候再去建立:

執行緒池執行緒數:0,佇列長度0

呼叫第1個任務

執行緒池執行緒數:1,佇列長度0

呼叫第2個任務

執行緒池執行緒數:2,佇列長度0

呼叫第3個任務

執行緒池執行緒數:3,佇列長度0

呼叫第4個任務

執行緒池執行緒數:4,佇列長度0

呼叫第5個任務

執行緒池執行緒數:5,佇列長度0

呼叫第6個任務

執行緒池執行緒數:5,佇列長度1

呼叫第7個任務

執行緒池執行緒數:5,佇列長度2

呼叫第8個任務

執行緒池執行緒數:5,佇列長度3

呼叫第9個任務

執行緒池執行緒數:5,佇列長度4

呼叫第10個任務

執行緒池執行緒數:5,佇列長度5

呼叫第11個任務

執行緒池執行緒數:5,佇列長度6

呼叫第12個任務

執行緒池執行緒數:5,佇列長度7

呼叫第13個任務

執行緒池執行緒數:5,佇列長度8

呼叫第14個任務

執行緒池執行緒數:5,佇列長度9

呼叫第15個任務

執行緒池執行緒數:5,佇列長度10

呼叫第16個任務

執行緒池執行緒數:6,佇列長度10

呼叫第17個任務

執行緒池執行緒數:7,佇列長度10

呼叫第18個任務

執行緒池執行緒數:8,佇列長度10

呼叫第19個任務

執行緒池執行緒數:9,佇列長度10

呼叫第20個任務

完成第1個任務

完成第2個任務

完成第3個任務

完成第4個任務

完成第5個任務

完成第18個任務

完成第19個任務

完成第20個任務

完成第17個任務

完成第16個任務

任務呼叫完成

完成第6個任務

完成第7個任務

完成第10個任務

完成第9個任務

完成第8個任務

執行緒池執行緒數:9,佇列長度0

完成第13個任務

完成第12個任務

完成第14個任務

完成第11個任務

完成第15個任務

執行緒池執行緒數:9,佇列長度0

執行緒池執行緒數:5,佇列長度0

執行緒池執行緒數:5,佇列長度0

執行緒池執行緒數:5,佇列長度0

執行緒池執行緒數:5,佇列長度0

簡要分析任務與執行緒池

說執行緒還是任務,我們都不可避免的要討論下執行緒池,然而在.net 4.0以後,執行緒池引擎考慮了未來的擴充套件性,已經充分利用多核微處理器 架構,只要在可能的情況下,我們應該盡量使用task,而不是執行緒池。首先看一下task的結構 從圖中我們可以看出task.factory.startnew 貌...

java執行緒池(2) 執行緒池新增任務的過程(原理)

上一期簡單的聊了一下執行緒池的建立。這一期我們就,稍微熟悉一下執行緒池執行任務的過程吧!執行緒池的工作原理是怎麼樣的呢?首先,我用圖來說明吧!這裡可以看到有乙個任務佇列,然後還有乙個工作的執行緒池。今天主要將的就是向任務佇列中新增任務的過程!對於執行緒池我們上一期是做了乙個稍微的解釋的。我們構建執行...

執行緒池概念,任務

問題 執行緒是寶貴的記憶體資源,單個執行緒約佔1mb空間,過多分配易造成記憶體溢位 頻繁的建立及銷毀執行緒會增加虛擬機器 頻率 資源開銷,造成程式效能下降 執行緒池 執行緒容器,可設定執行緒分配的數量上限 將預先建立的執行緒物件存入池中,並重用執行緒池中的執行緒物件 避免頻繁的建立和銷毀 將任務提交...