Java 線程池之Jetty 線程池學習總結 前提 Jetty 11.0.x 為什麼是Jetty? Java提供4中創建線程池的快捷方式 Executors.newFixedThreadPool(); Executors.newCachedThreadPool(); Executors.newSin ...
Java 線程池之Jetty 線程池學習總結
前提
Jetty 11.0.x
為什麼是Jetty?
Java提供4中創建線程池的快捷方式
Executors.newFixedThreadPool();
Executors.newCachedThreadPool();
Executors.newSingleThreadExecutor();
Executors.newScheduledThreadPool();
但通常我們很少用這4個工廠方法去創建線程池,而是直接使用ThreadPoolExecutor
類構造線程池,因為這些工廠方法最終也是調用這個類來創建線程池的。
眾所周知,雖然ThreadPoolExecutor
提供了corePoolSize
和maximumPoolSize
兩個參數來控制線程池的基本大小和最大大小,但是這兩個參數並不是那麼好用:當任務隊列採用SynchronousQueue
時,通常需要無界的maximumPoolSize
;當任務隊列採用無界隊列時,maximumPoolSize
的值又相當於不起作用;當任務隊列採用有界隊列時,僅在任務隊列已滿,且未達到maximumPoolSize
時才會擴充線程池大小。
既然如此,那有沒有一種更簡單的實現方案呢?使用該方案,使用者只需要簡單的配置下線程池的基本大小和最大大小,程式就可以根據任務的繁忙程度自動調整當前線程數量。答案是有的:Jetty--一個基於Java的web容器,和Tomcat齊名
Jetty線程池介紹
任務處理流程
初始化線程池
程式初始化運行時,會先創建線程池,線程池大小預設為minThreads
,也就是說會預先創建minThreads
個線程,線程名稱格式形如“qtp1076496284-13”
創建線程池時:
-
如果未指定最大線程數(
maxThreads
),則預設為 200; -
如果未指定最小線程數(
minThreads
),則預設為 8 -
如果未指定線程空閑超時時間(
idleTimeout
),則預設為 60000,即60秒 -
保留線程數(
reservedThreads
)預設為 -1 -
如果未指定任務隊列,則預設創建
BlockingArrayQueue
任務隊列,容量大小為 8 x 1024 -
如果指定的最大線程數小於最小線程數,則拋出異常
線程池擴縮容
- 當前線程數比最小線程數小,或者沒有空閑的線程,且當前線程數(
threads
)小於最大線程數,則創建線程; idleTimout
大於0且當前線程數大於最小線程數,且線程空閑時間超過idleTimeout
,則停止線程
註意:程式判斷是否存在空閑線程的邏輯是這樣的:Net空閑線程數 = 空閑線程數 - 任務隊列大小,如果“Net空閑線程數”為負數,則表示不存在空閑線程,即需要更多的線程來處理任務。
任務隊列及線程相關定義
queueSize
任務隊列大小,即隊列中等待被線程執行的任務數。可通過getQueueSize()
函數獲取。
threads
當前線程池中的線程數,包括已租給內部組件的線程、空閑線程、保留線程,以及正在執行臨時作業的線程。threads
= readyThreads
+ leasedThreads
+ utilizedThreads
。 可通過getThreads()
函數獲取。
readyThreads
準備執行臨時任務的線程數。readyThreads
= idleThreads
+ availableReservedThreads
。可通過getReadyThreads()
函數獲取。
idleThreads
未被保留的空閑線程數。idleThreads
= readyThreads
- availableReservedThreads
。可通過getIdleThreads()
函數獲取。
reservedThreads
保留的線程數,預設值為-1。可通過getReservedThreads()
函數獲取。
availableReservedThreads
可用的保留線程。可通過getAvailableReservedThreads()
函數獲取。
leasedThreads
供內部組件使用,用於執行內部任務的線程。需要線程的Jetty組件(比如網路acceptors
和selector
)可能會使用ThreadPoolBudget
從線程池中租用線程。站線上程池的角度來看,這些被租用的線程是活躍的,但是不能用於執行臨時任務,比如一個HTTP請求,或者一個WebSocket幀。QueuedThreadPool
有一個ReservedThreadExecutor
,該組件會從線程池租用線程,但會讓這些線程可用,就像它們是“idle”線程一樣。線程池啟動後,該值一般是恆定的。可通過getLeasedThreads()
函數獲取。
minThreads
線程池中的最小線程數。可通過getMinThreads()
函數獲取。
maxThreads
線程池中的最大線程數。可通過getMaxThreads()
函數獲取。
maxAvailableThreads
可用於執行臨時任務的最大線程數。maxAvailableThreads
= maxThreads
- leasedThreads
可通過getMaxAvailableThreads()
函數獲取。
utilizedThreads
執行臨時任務的線程數,可通過getUtilizedThreads()
函數獲取。utilizedThreads
= threads
- leasedThreads
- readyThreads
utilizationRate
= utilizedThreads
/ maxAvailableThreads
執行臨時任務的線程利用率。該值為0.0D
則表示線程池未被利用,如果為1.0D
則表示線程池被充分利用於執行臨時任務。可通過getUtilizationRate()
函數獲取。
busyThreads
正在執行內部任務和臨時任務的線程數。 busyThreads
= utilizedThreads
+ leasedThreads
。可通過getBusyThreads()
函數獲取。
參考鏈接
https://www.eclipse.org/jetty/javadoc/jetty-11/org/eclipse/jetty/util/thread/QueuedThreadPool.html
作者:授客
微信/QQ:1033553122
全國軟體測試QQ交流群:7156436
Git地址:https://gitee.com/ishouke
友情提示:限於時間倉促,文中可能存在錯誤,歡迎指正、評論!
作者五行缺錢,如果覺得文章對您有幫助,請掃描下邊的二維碼打賞作者,金額隨意,您的支持將是我繼續創作的源動力,打賞後如有任何疑問,請聯繫我!!!
微信打賞
支付寶打賞 全國軟體測試交流QQ群