執行緒池的狀態含義
執行緒池引數
執行緒池種類(使用樣例)
executors工廠類
執行緒池的調優策略
上乙個文章說多執行緒的實現方法有四個,其中第四個有提到exectorservice介面與callable與runnable,futrue等的一起實現,exectorservice是執行緒的管理工具。它一般有兩個實現類,abstractexecutorservice, scheduledthreadpoolexecutor
,其中threadpoolexecutor
繼承abstractexecutorservice
,我們通常用threadpoolexecutor
來實現執行緒池。
我們之前說起多執行緒的時候都是需要乙個執行緒就開啟乙個執行緒來處理任務,就是我們通常的new thread(),主要會有下面的一些缺點:新建物件的效能比較差,缺乏統一管理,無限制的建立執行緒,相互競爭,占用過多的系統資源導致宕機。
特別是:當處理任務的時間小於建立執行緒和銷毀執行緒的時間和,那麼頻繁的建立執行緒就會很占用cpu,所以我們想到復用的方法來處理任務和執行緒之間的「矛盾」,應運而生的便是執行緒池。
重用存在的執行緒,減少物件的建立,消亡的開銷,效能佳;有效控制最大的併發執行緒的數量,提高資源的使用率,避免過多資源競爭,避免堵塞;提供定時執行,定期執行,單執行緒,併發數的控制。
池子裡有最多可以容納n個執行緒,一般都存在的執行緒個數有m個(m<=n),在這m個執行緒中可能有正在執行的執行緒,可能有空閒的執行緒,我們提供乙個外部傳參的方法,把任務傳進來,然後把需要處理的任務存進乙個資料結構,比如佇列裡,中間會有個通過執行緒管理工具對任務進行分配給空閒的執行緒,其實就會有這麼幾種情況:
1.任務進來的時候,有空閒的執行緒或者執行緒數目沒有達到最大的時候,我們可以直接不用存在佇列就可以利用執行緒處理或者建立執行緒處理佇列;
2.當任務來的時候,任務佇列還沒有存滿那就直接的存在任務佇列中;
3.任務佇列已經存滿了,那就可能拋棄舊有的任務來儲存新來的任務。
此佇列是阻塞佇列
接收新的任務並且處理阻塞佇列裡的新任務
拒絕新的任務但是處理阻塞佇列裡的任務
拒絕新任務並且拋棄阻塞佇列裡的任務,中斷正在處理的任務
所有的任務都處理完之後當前執行緒池活動的執行緒數為0,將呼叫terminated方法
終止狀態
corepoolsize
:執行緒池核心執行緒個數,其實就是上面說的n。執行緒的基本大小,即在沒有任務需要執行的時候執行緒池的大小。
maximunpoolsize
:執行緒池最大的執行緒數量,當佇列滿,並且當前執行緒個數小於maximunpoolsize
時,就會建立新的執行緒來執行任務。
largestpoolsize
:該變數記錄了執行緒池在整個生命週期中曾經出現的最大執行緒個數。
poolsize
:執行緒池中當前執行緒的數量。
keepalivetime
:存活時間,若是當前執行緒池中的執行緒數量大於核心執行緒的數量,並且是閒置狀態,這就是這些閒置執行緒能存活的最大時間。當keepalivetime=0
時,證明只要當前執行緒個數大於核心執行緒個數,並且當前執行緒閒置則**。
newsinglethreadexecutor
:建立乙個單執行緒化的執行緒池,它只會用唯一的工作執行緒來執行任務,保證所有任務按照指定的順序執行。
newfixedthreadpool
:建立定長線程池,可控制最大併發數,超出的執行緒會在佇列中等待,當keepalivetime=0
時,只要當前執行緒個數大於核心執行緒個數,並且當前執行緒閒置則**;
newcachedthreadpool
:建立乙個按需建立執行緒的執行緒池,初始執行緒個數為0,阻塞隊列為同步佇列,keepalivetime
=60,當前執行緒只要空閒60秒就需要被**;
newscheduledthreadpool
:建立乙個定長線程池,支援定時及週期性任務執行;
提供建立執行緒池的幾種方法
先建立執行緒池——>呼叫submit將執行緒物件提交到執行緒池中,不需要提交執行緒了就呼叫shutdown()
關閉執行緒池。
submit
的原型在父類abstractexecutorservice
裡。
參考:
keep it ******,stupid
將最小的執行緒數和最大執行緒數設定為相同,儲存任務方面,若適合無界佇列,則選擇linkedblockingqueue
;若適合有界,則arrayblockingqueue
一般而言,對於執行緒數為最小值的執行緒池,乙個新執行緒一旦建立出來,至少應該保留幾分鐘,以處理任何負載飆公升。空閒時間應該以分鐘計,而且至少在10分鐘到30分鐘之間,這樣可以防止頻繁建立執行緒。
取決於負載特性以及底層硬體。特別是,最優執行緒數還與每個任務阻塞的頻率有關。
當有空閒執行緒的時候從佇列拉出乙個任務,佇列的任務可能特別大,則,後面的任務可能等待的時間就會相當的漫長,直到前面的任務執行完畢。
關於任務佇列的大小只能靠我們真是的測量。
建立執行緒池的時候建立最小的執行緒數,若是來乙個任務就看有沒有空閒的執行緒處理,若是有則直接處理,若是沒有則判斷是否達到最大的執行緒數,沒有就建立執行緒處理,若是達到了,就加入等待的佇列中,若是無法新增任務則拒絕此任務。
同步佇列:synchronousqueue
執行緒池的行為和我們預期的一樣,它會考慮執行緒數:如果所有的執行緒都在忙碌,而且池中的執行緒數尚未達到最大,則會為新任務啟動乙個新執行緒;然而這個佇列沒辦法儲存等待的任務:如果來了乙個任務,建立的執行緒數已經達到最大值,而且所有的執行緒都在忙碌,則新的任務都會被拒絕,所以如果是管理少量的任務,這是個不錯的選擇,對於其他的情況就不適合了。
無界佇列:linkedblockingqueue
不會拒絕任何任務(因為佇列大小沒有限制)。這種情況下,threadpoolexecutor最多僅會按照最小執行緒數建立執行緒,也就是說最大執行緒池大小被忽略了。如果最大執行緒數和最小執行緒數相同,則這種選擇和配置了固定執行緒數的傳統執行緒池執行機制最為接近。
有界佇列:arrayblockingqueue
如果佇列已滿,而又有新任務進來,此時才會啟動乙個新執行緒,這裡不會因為佇列已滿而拒接該任務,相反會啟動乙個新執行緒。新執行緒會執行佇列中的第乙個任務,為新來的任務騰出空間。
JAVA多執行緒之 執行緒池
執行緒池顧名思義,就是乙個放置執行緒的池子。就跟資料庫連線池差不多。執行緒池通過對併發執行緒的控制,能有效的節省系統資源的浪費,提高系統的效能。學習執行緒池,先了解一下執行緒池的乙個基本結構 executor是乙個介面,其中只有乙個方法,就是execute方法。所以executor實際就是乙個執行緒...
Java多執行緒及執行緒池
提問 我開啟了乙個qq 又開啟了乙個遊戲,請問我開啟了兩個執行緒嗎?回答 概念理解錯誤,你其實開啟是兩個程序,為什麼呢,請看概念 程序是正在執行的程式,是系統呼叫資源和進行資源分配的基本單位。比如所說的qq 和乙個遊戲,這就是兩個正在執行的程式。我們的作業系統都是多程序的。繼續提問 早期的計算機是單...
java多執行緒,spring配置執行緒池
實際專案中用到多執行緒,提供spring配置執行緒池完整 如下 本專案用的jar包為基本的spring配置jar包 1 properties配置檔案中線程池引數 taskexecutor.corepoolsize 100 taskexecutor.keepaliveseconds 10 taskex...