<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
執行緒池的技術在專案中使用廣泛,執行緒池提供了四種拒絕策略,大家是否瞭解這四種拒絕的策略呢?本文將詳細的講解ThreadPoolExecutor的四種拒絕策略,以及相關的注意事項。
執行緒池的原理如下圖:
說明:
執行緒池為我們提供了四種拒絕策略分別是:CallerRunsPolicy,AbortPolicy,DiscardPolicy,DiscardOldestPolicy
ThreadPoolExecutor中預設的拒絕策略就是AbortPolicy直接丟擲異常,具體實現如下
public static class AbortPolicy implements RejectedExecutionHandler { public AbortPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); } }
說明:這種策略非常簡單粗暴,直接丟擲RejectedExecutionException異常,也不會執行後續的任務。
範例說明:
public class ThreadPoolTest { public static void main(String[] args) { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, 5, 10, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(1), new ThreadPoolExecutor.AbortPolicy()); //非同步執行 for(int i=0; i<10;i++) { System.out.println("新增第"+i+"個任務"); threadPoolExecutor.execute(new TestThread("執行緒"+i)); } } } public class TestThread implements Runnable { private String name; public TestThread(String name){ this.name=name; } @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread name:"+Thread.currentThread().getName()+",執行:"+name); } }
執行結果:
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.skywares.fw.juc.thread.TestThread@55f96302 rejected from java.util.concurrent.ThreadPoolExecutor@3d4eac69[Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
at com.skywares.fw.juc.thread.ThreadPoolTest.main(ThreadPoolTest.java:26)
thread name:pool-1-thread-5,執行:執行緒5
thread name:pool-1-thread-2,執行:執行緒1
thread name:pool-1-thread-4,執行:執行緒4
thread name:pool-1-thread-3,執行:執行緒3
thread name:pool-1-thread-1,執行:執行緒0
thread name:pool-1-thread-5,執行:執行緒2
從執行結果我們得知,採用AbortPolicy策略當任務執行到第七個任務時會直接報錯,導致後續的業務邏輯不會執行。
CallerRunsPolicy在任務被拒絕新增後,會用呼叫execute函數的上層執行緒去執行被拒絕的任務。
相關範例
public class ThreadPoolTest { public static void main(String[] args) { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, 5, 10, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(1), new ThreadPoolExecutor.CallerRunsPolicy()); //非同步執行 for(int i=0; i<10;i++) { System.out.println("新增第"+i+"個任務"); threadPoolExecutor.execute(new TestThread("執行緒"+i)); } } }
執行結果:
新增第0個任務
新增第1個任務
新增第2個任務
新增第3個任務
新增第4個任務
新增第5個任務
新增第6個任務
thread name:main,執行:執行緒6
thread name:pool-1-thread-3,執行:執行緒3
thread name:pool-1-thread-1,執行:執行緒0
thread name:pool-1-thread-4,執行:執行緒4
thread name:pool-1-thread-2,執行:執行緒1
thread name:pool-1-thread-5,執行:執行緒5
新增第7個任務
新增第8個任務
thread name:main,執行:執行緒8
thread name:pool-1-thread-1,執行:執行緒7
thread name:pool-1-thread-3,執行:執行緒2
新增第9個任務
thread name:pool-1-thread-1,執行:執行緒9
從執行的結果我們可以得知,當執行到第7個任務時,由於執行緒池拒絕策略,此任務由主執行緒來執行,當執行緒池有空閒時,才繼續執行其他的任務。所以此策略可能會阻塞主執行緒。
這種拒絕策略比較簡單,執行緒池拒絕的任務直接拋棄,不會拋異常也不會執行
修改上述的程式碼,將拒絕策略修改為DiscardPolicy
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, 5, 10, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(1), new ThreadPoolExecutor.CallerRunsPolicy());
invoke dealStock success
goodsId:手機
thread name:pool-1-thread-1,執行:執行緒0
thread name:pool-1-thread-4,執行:執行緒4
thread name:pool-1-thread-5,執行:執行緒5
thread name:pool-1-thread-3,執行:執行緒3
thread name:pool-1-thread-2,執行:執行緒1
thread name:pool-1-thread-1,執行:執行緒2
從執行的結果來看只執行了6個任務,其他的任務都被拋棄了。
DiscardOldestPolicy 當任務拒絕新增時,會拋棄任務佇列中最先加入佇列的任務,再把新任務新增進去。
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 1, 2, 10, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(2), new ThreadPoolExecutor.CallerRunsPolicy());
執行結果:
新增第0個任務
新增第1個任務
新增第2個任務
新增第3個任務
新增第4個任務
新增第5個任務
invoke dealStock success
goodsId:手機
thread name:pool-1-thread-2,執行:執行緒3
thread name:pool-1-thread-1,執行:執行緒0
thread name:pool-1-thread-1,執行:執行緒2
thread name:pool-1-thread-2,執行:執行緒1
當執行緒池提供的拒絕策略無法滿足要求時,我們可以採用自定義的拒絕策略,只需要實現RejectedExecutionHandler介面即可
public class CustRejectedExecutionHandler implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { new Thread(r,"執行緒:"+new Random().nextInt(10)).start(); } } ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 1, 2, 10, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(2), new CustRejectedExecutionHandler());
執行結果:
thread name:客戶執行緒:6,執行:執行緒5
thread name:pool-1-thread-1,執行:執行緒0
thread name:客戶執行緒:8,執行:執行緒4
thread name:pool-1-thread-2,執行:執行緒3
thread name:pool-1-thread-1,執行:執行緒1
thread name:pool-1-thread-2,執行:執行緒2
從執行的結果來看,被拒絕的任務都在客戶的新執行緒中執行。
本文對於執行緒的池的幾種策略進行詳細的講解,在實際的生產中需要集合相關的場景來選擇合適的拒絕策略,如有疑問,請隨時反饋。
到此這篇關於Java ThreadPoolExecutor的拒絕策略的文章就介紹到這了,更多相關Java ThreadPoolExecutor拒絕策略內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45