我們創建線程的常見方式一般有繼承Thread類以及實現Runnable接口,其實Thread類也是實現了Runnable接口。通過這兩種方式創建的線程,在執行完畢之后都會被銷毀,這樣頻繁的創建和銷毀線程是一件很浪費資源到的事情。那么,有沒有什么辦法解決這個問題呢?通過創建線程池就可以解決這個問題。
通過線程池創建的線程執行完畢之后並不會銷毀,而是會回到線程池繼續重復利用,執行其他任務。這里簡單介紹一下線程池的幾個主要參數:
一、核心參數
- corePoolSize(核心線程數)
(1)核心線程會一直存在,即使沒有任務執行;
(2)當線程數小於核心線程數的時候,即使有空閑線程,也會一直創建線程直到達到核心線程數;
(3)設置allowCoreThreadTimeout=true(默認false)時,核心線程會超時關閉。 - queueCapacity(任務隊列容量)
也叫阻塞隊列,當核心線程都在運行,此時再有任務進來,會進入任務隊列,排隊等待線程執行。 - maxPoolSize(最大線程數)
(1)線程池里允許存在的最大線程數量;
(2)當任務隊列已滿,且線程數量大於等於核心線程數時,會創建新的線程執行任務;
(3)線程池里允許存在的最大線程數量。當任務隊列已滿,且線程數量大於等於核心線程數時,會創建新的線程執行任務。 - keepAliveTime(線程空閑時間)
(1)當線程空閑時間達到keepAliveTime時,線程會退出(關閉),直到線程數等於核心線程數;
(2)如果設置了allowCoreThreadTimeout=true,則線程會退出直到線程數等於零。 - allowCoreThreadTimeout(允許核心線程超時)
- rejectedExecutionHandler(任務拒絕處理器)
(1)當線程數量達到最大線程數,且任務隊列已滿時,會拒絕任務;
(2)調用線程池shutdown()方法后,會等待執行完線程池的任務之后,再shutdown()。如果在調用了shutdown()方法和線程池真正shutdown()之間提交任務,會拒絕新任務。
二、線程池參數默認值
- corePoolSize = 1
- queueCapacity = Integer.MAX_VALUE
- maxPoolSize = Integer.MAX_VALUE
- keepAliveTime = 60秒
- allowCoreThreadTimeout = false
- rejectedExecutionHandler = AbortPolicy()
三、ThreadPoolExecutor(線程池)執行順序
- 當線程數小於核心線程數時,會一直創建線程直到線程數等於核心線程數;
- 當線程數等於核心線程數時,新加入的任務會被放到任務隊列等待執行;
- 當任務隊列已滿,又有新的任務時,會創建線程直到線程數量等於最大線程數;
- 當線程數等於最大線程數,且任務隊列已滿時,新加入任務會被拒絕。