Java執行緒池newCachedThreadPool()與newFixedThreadPool()區別 | Baeldung
當涉及執行緒池實現時,Java標準庫提供了很多選擇。在這些實現中,固定執行緒池和快取執行緒池非常普遍。
快取執行緒池newCachedThreadPool
Executors.newCachedThreadPool快取執行緒池是從零個執行緒開始,並且可能會增長為具有 Integer.MAX_VALUE個 執行緒。實際上,快取執行緒池的唯一限制是可用的系統資源。
為了更好地管理系統資源,快取的執行緒池將刪除閒置一分鐘的執行緒。為了更好地管理系統資源,快取的執行緒池將刪除閒置一分鐘的執行緒。
假設有一個新任務進入。如果佇列中有一個空閒執行緒正在等待,則任務生產者將任務移交給該執行緒。否則,由於佇列始終已滿,執行程式將建立一個新執行緒來處理該任務。
快取執行緒池配置會在很短的時間內快取執行緒(因此命名),以將其重用於其他任務。因此,當我們處理相當數量的短期任務時,它最有效。
這裡的關鍵是“合理”和“短暫”。為了澄清這一點,讓我們評估一個快取池不太適合的情況。在這裡,我們將提交100萬個任務,每個任務需要100微秒的時間來完成:
allable<String> task = () -> { long oneHundredMicroSeconds = 100_000; long startedAt = System.nanoTime(); while (System.nanoTime() - startedAt <= oneHundredMicroSeconds); return "Done"; }; var cachedPool = Executors.newCachedThreadPool(); var tasks = IntStream.rangeClosed(1, 1_000_000).mapToObj(i -> task).collect(toList()); var result = cachedPool.invokeAll(tasks); |
這將建立許多執行緒,這些執行緒會轉換為不合理的記憶體使用,甚至更糟的是,還會有許多CPU上下文切換。這兩個異常都會嚴重損害整體效能。
因此,當執行時間不可預測時(如IO繫結任務),我們應避免使用快取執行緒池。
固定執行緒池newFixedThreadPool
與快取執行緒池相反,該執行緒正在使用具有固定數量的永不過期執行緒的無界佇列。因此,固定執行緒池不是使用數量不斷增加的執行緒,而是嘗試使用固定數量的執行緒執行傳入的任務。當所有執行緒都忙時,執行程式將對新任務進行排隊。這樣,我們可以更好地控制程式的資源消耗。
因此,固定執行緒池更適合執行時間無法預測的任務。
共同點
除了所有這些差異,它們都使用 AbortPolicy 作為飽和策略。因此,我們希望這些執行器在無法接受甚至無法排隊任務時丟擲異常。
讓我們看看現實世界中發生了什麼。
在極端情況下,快取執行緒池將繼續建立越來越多的執行緒,因此,實際上,它們永遠不會達到飽和點。同樣,固定執行緒池將繼續在其佇列中新增越來越多的任務。因此,固定池也永遠不會達到飽和點。
由於兩個池都不會飽和,因此當負載異常高時,它們將消耗大量記憶體來建立執行緒或排隊任務。更糟的是,快取的執行緒池也將導致很多處理器上下文切換。
無論如何,為了更好地控制資源消耗,強烈建議建立一個自定義 ThreadPoolExecutor:
var boundedQueue = new ArrayBlockingQueue<Runnable>(1000); new ThreadPoolExecutor(10, 20, 60, SECONDS, boundedQueue, new AbortPolicy()); |
在這裡,我們的執行緒池最多可以有20個執行緒,最多隻能排隊1000個任務。同樣,當它不能再接受任何負載時,它只會丟擲一個異常。
相關文章
- Java執行緒池二:執行緒池原理Java執行緒
- java--執行緒池--建立執行緒池的幾種方式與執行緒池操作詳解Java執行緒
- java中常見的四種執行緒池的區別Java執行緒
- java 執行緒池Java執行緒
- Java執行緒池Java執行緒
- java多執行緒與併發 - 執行緒池詳解Java執行緒
- Java多執行緒-鎖的區別與使用Java執行緒
- java執行緒池趣味事:這不是執行緒池Java執行緒
- 程式與執行緒區別執行緒
- java多執行緒9:執行緒池Java執行緒
- Java多執行緒學習(八)執行緒池與Executor 框架Java執行緒框架
- 搞懂Java執行緒池Java執行緒
- 【Java】【多執行緒】執行緒池簡述Java執行緒
- Java執行緒池一:執行緒基礎Java執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- 程式與執行緒的區別執行緒
- java中執行緒池的生命週期與執行緒中斷Java執行緒
- SpringBoot執行緒池和Java執行緒池的實現原理Spring Boot執行緒Java
- Python執行緒池與程式池Python執行緒
- Android程式框架:執行緒與執行緒池Android框架執行緒
- Java 執行緒中斷(interrupt)與阻塞 (park)的區別Java執行緒
- Java執行緒池之ThreadPoolExecutorJava執行緒thread
- java-執行緒池(一)Java執行緒
- 速讀Java執行緒池Java執行緒
- Java執行緒池詳解Java執行緒
- JAVA執行緒池的使用Java執行緒
- Java執行緒池進階Java執行緒
- java執行緒池實踐Java執行緒
- Java執行緒池歸納Java執行緒
- Java 執行緒池詳解Java執行緒
- 執行緒與執行緒池的那些事之執行緒池篇(萬字長文)執行緒
- Linux程式與執行緒的區別Linux執行緒
- Linux執行緒與程式的區別Linux執行緒
- 深入淺出Java多執行緒(十二):執行緒池Java執行緒
- java多執行緒:執行緒池原理、阻塞佇列Java執行緒佇列
- 《Java 高階篇》七:執行緒和執行緒池Java執行緒
- Java利用執行緒工廠監控執行緒池Java執行緒
- 詳解執行緒池的作用及Java中如何使用執行緒池執行緒Java