一、線程池策略選擇
線程池在多線程編程中起到了至關重要的作用,可以有效地管理線程,提高系統的性能,降低線程創建和銷毀帶來的開銷。在使用線程池時,我們需要注意選擇適合當前系統的線程池策略。
Java提供的線程池主要有四種策略:
- FixedThreadPool:一個固定大小的線程池,管理一組最多的線程,如果有多餘的任務,則將其放入隊列中等待運行。
- CachedThreadPool:一個可變大小的線程池,根據需要創建新線程,當有線程空閑時會重複利用已創建的線程。
- SingleThreadExecutor:只有一個線程的線程池,順序執行每一個任務。
- ScheduledThreadPool:類似於FixedThreadPool,但可以定時執行任務或延遲執行任務。
二、線程池什麼時候觸發拒絕策略
當線程池中線程的數量達到最大值並且任務隊列已經滿時,新提交的任務將會觸發線程池拒絕策略。
三、線程池策略模式
線程池使用策略模式來定義不同的拒絕策略。Java提供了四種默認的拒絕策略:AbortPolicy、CallerRunsPolicy、DiscardOldestPolicy和DiscardPolicy。
四、線程池拒絕策略參數
線程池中有兩個參數與拒絕策略相關:corePoolSize和maximumPoolSize。corePoolSize 表示線程池中核心線程的數量,maximumPoolSize 表示線程池中最大線程的數量。如果線程池中線程數量未達到 corePoolSize,則會創建一個新的線程執行任務;如果達到 corePoolSize 並且任務隊列已滿,則會按照線程池策略拒絕任務。
五、線程池策略CallerRunsPolicy
CallerRunsPolicy 是 JDK 內置的拒絕策略之一,當線程池無法執行任務時,將任務直接交給調用 execute 方法的線程執行。
public class CallerRunsPolicy implements RejectedExecutionHandler { public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { r.run(); } } }
六、線程池拋棄策略
DiscardPolicy 是 JDK 內置的拒絕策略之一,當線程池無法執行任務時,直接丟棄該任務。
public class DiscardPolicy implements RejectedExecutionHandler { public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { // do nothing } }
七、線程池callrun策略
CallerRunsPolicy 是 JDK 內置的拒絕策略之一,當線程池無法執行任務時,將任務直接交給調用 execute 方法的線程執行。
public class CallerRunsPolicy implements RejectedExecutionHandler { public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { r.run(); } } }
八、線程池應該採取哪種拒絕策略
選擇線程池拒絕策略需要根據實際場景,不同的拒絕策略有不同的應用場景。
- AbortPolicy:默認的拒絕策略,在任務無法執行時直接拋出異常。
- CallerRunsPolicy:當線程池中已有正在執行的線程時,調用 execute 方法的線程將直接執行待執行的任務。
- DiscardPolicy:當任務無法執行時直接丟棄該任務。
- DiscardOldestPolicy:當任務無法執行時丟棄一些隊列中最老的任務,並將新任務加入隊列。
九、線程池拒絕策略
用戶也可以自定義拒絕策略,只需實現 RejectedExecutionHandler 接口並實現 rejectedExecution 方法即可。例如,我們可以將無法執行的任務寫入日誌等。
public class MyRejectedExecutionHandler implements RejectedExecutionHandler { public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { // my custom rejection policy } }
十、線程池飽和策略選取
線程池的飽和策略選取需要根據實際情況進行選擇。如果希望能夠快速響應並拋出異常,則可以選擇 AbortPolicy 等策略;如果希望利用已有線程執行任務,則可以選擇 CallerRunsPolicy 等策略;如果希望最大限度地利用系統資源,則可以選擇 DiscardOldestPolicy 或自定義拒絕策略。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/283729.html