線程池基礎
線程池是什麼、有什麼用?
線程池是一種線程使用形式。
- 減少資源損耗:建立/銷毀線程需要消耗系統資源,線程池可以複用已建立的線程,同時可以控制線程數量
- 提高相應速度:可以使用線程池中閑置的線程,而不必等待線程的建立
- 有利于管理
7大參數
參數類型 | 參數名 | 含義 |
---|---|---|
int | corePoolSize | 核心線程數最大值 |
maximumPoolSize | 線程總數最大值 | |
long | keepAliveTime | 非核心線程線程最大閑置時間 |
TimeUnit | unit | keepAliveTime屬性的機關 |
BlockingQueue<Runnable> | workQueue | 等待隊列 |
ThreadFactory | threadFactory | 線程工廠 |
RejectedExecutionHandler | handler | 拒絕政策者 |
下面我們簡單介紹一下這些參數的含義
-
corePoolSize
:核心線程數最大值
線程池中有兩種線程,一個是核心線程另一個是非核心線程。核心線程在預設情況下會一直存在于線程池之中,不因為閑置時間過長而被銷毀。(當然,也可以通過設定
allowCoreThreadTimeOut
的值為true,使得核心線程也會被銷毀,預設值為false)。
關于這個核心線程數最大值有這樣一個預設規則:
CPU密集型任務,設定核心線程數為CPU核心數+1;IO密集型任務,設定核心線程數為CPU核心數*2
-
maximumPoolSize
:線程總數最大值
指定線程總數的上限。線程總數 = 核心線程數 + 非核心線程數
-
keepAliveTime
:線程閑置時間
預設情況下是為了去銷毀非核心線程,當一個非核心線程空閑時間大于這個空閑等待時間時,這個非核心線程将會被銷毀
-
unit
:線程閑置時間的時間機關
是一個枚舉屬性,包括以下屬性:
- NANOSECONDS:微毫秒/納秒 10^(-9) 秒
- MICROSECONDS:微妙 10^(-6)秒
- MILLISECONDS:毫秒 10^(-3)秒
- SECONDS:秒
- MINUTES:分鐘
- HOURS:小時
- DAYS:天
-
workQueue
:阻塞隊列
當線程不夠用時,将想要執行的任務放于阻塞隊列之中,常用的4個阻塞隊列有:
-
LinkedBlockingQueue:
鍊式阻塞隊列,底層資料結構是連結清單,預設大小是
Integer.MAX_VALUE
-
ArrayBlockingQueue:
數組阻塞隊列,底層資料結構是數組,需要指定隊列大小
-
SynchronousQueue:
同步隊列,内部容量為0,每個put操作必須等待一個take操作,反之亦然
-
DelayQueue:
延遲隊列,該隊列中的元素隻有當其指定的延遲時間到了,才能從該隊列中擷取元素
-
以上5個是必須參數,接下來介紹兩個非必須的參數
-
threadFactory
:建立線程的工廠
用于批量建立線程,統一在建立程序時設定一些參數,如是否為守護線程、線程的優先級等,若不進行指定,則建立一個預設的工廠
-
handler
:拒絕處理政策
當線程數量大于最大線程數時就會采用拒絕處理政策,常用的有以下四種:
-
ThreadPoolExecutor.AbortPolicy:
是預設的決絕政策,丢棄任務并抛出一個
異常RejectedExecutionException
-
ThreadPoolExecutor.DiscardPolicy:
隻丢棄任務,不抛出異常
-
ThreadPoolExecutor.DiscardOldestPolicy:
丢棄隊列頭部的任務,并繼續嘗試執行執行任務(一直重複該過程)
-
ThreadPoolExecutor.CallerRunPolicy:
由調用線程處理該任務
-
4種常見線程池
-
newCachedThreadPool:
建立一個沒有核心線程、最大線程數量為Integer.MAX_VALUE、預設等待時間為60s、阻塞隊列為同步隊列的線程池。好處在于每一個任務都會被馬上執行,壞處是當任務數過大會建立大量線程導緻系統崩潰
-
newFixedThreadPool:
建立一個有且隻有隻有核心線程、線程數由使用者指定的、阻塞隊列為鍊式阻塞隊列的線程池。好處是線程不會被回收,有較高的響應速度。壞處是阻塞隊列沒有上限,任務過多可能會崩潰
- newSingleThreadExecutor: