一、基本概念
線程池是在實際項目中經常使用的一種技術,它可以提高程序的效率,同時也可以避免頻繁的線程創建和銷毀的開銷。線程池中包含着若干個線程,這些線程能夠接收程序傳遞過來的任務,並按照一定的策略來執行這些任務。在線程池中,拒絕策略用於處理當線程池中的線程資源不足時,向調用者返回一種拒絕策略,從而防止任務隊列中的任務出現無法被處理的情況。
二、線程池拒絕策略類型
Java中定義了四種拒絕策略,在使用線程池的時候可以根據實際情況選擇合適的拒絕策略,避免任務隊列中的任務無法被處理。下面我們來逐一介紹這四種線程池拒絕策略類型:
1. CallerRunsPolicy
如果線程池中的線程已經達到最大並發數,而且等待隊列已經被填滿,那麼新提交的任務將在調用這個線程池的execute()方法的線程中執行,也就是說,這個任務是會在提交這個任務的線程中執行的。這種情況下,由於任務是在調用者線程中執行,因此執行效率可能會受到一定的影響。
public class CallerRunsPolicy implements RejectedExecutionHandler { public CallerRunsPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { r.run(); } } }
2. AbortPolicy
這是線程池的默認拒絕策略。如果線程池中的線程已經達到最大並發數,而且等待隊列已經被填滿,那麼新提交的任務將會被拋棄,並拋出RejectedExecutionException異常。
public class AbortPolicy implements RejectedExecutionHandler { public AbortPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); } }
3. DiscardPolicy
這種策略會直接將新提交的任務拋棄,不做任何處理。如果隊列滿了,那麼後續的任務就會被忽略掉。
public class DiscardPolicy implements RejectedExecutionHandler { public DiscardPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { } }
4. DiscardOldestPolicy
這種策略會將最早提交的任務從隊列中移除,然後嘗試再次執行新提交的任務。
public class DiscardOldestPolicy implements RejectedExecutionHandler { public DiscardOldestPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { e.getQueue().poll(); e.execute(r); } } }
三、自定義拒絕策略
如果以上四種拒絕策略不能夠滿足實際需求,我們可以自己定義一種新的拒絕策略。在定義新的拒絕策略時,我們只需要實現RejectedExecutionHandler接口,並重寫其中的rejectedExecution方法就可以了。
public class CustomPolicy implements RejectedExecutionHandler { public CustomPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { // 自定義處理邏輯 } }
四、總結
線程池是一種非常常用的技術,它可以避免頻繁的線程創建和銷毀的開銷,提高程序的效率。在使用線程池時,線程池拒絕策略起着非常重要的作用,能夠防止任務隊列中的任務出現無法被處理的情況。在Java中,定義了四種線程池拒絕策略類型,使用者可以根據具體的情況進行選擇。同時,Java也支持自定義拒絕策略,當以上四種類型無法滿足實際需求時,我們可以根據實際情況定義新的拒絕策略。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/293713.html