Java线程池--拒绝策略RejectedExecutionHandler
當(dāng)線程池的任務(wù)緩存隊列已滿并且線程池中的線程數(shù)目達到maximumPoolSize,如果還有任務(wù)到來就會采取任務(wù)拒絕策略,通常有以下四種策略:
當(dāng)線程池的任務(wù)緩存隊列已滿并且線程池中的線程數(shù)目達到maximumPoolSize,如果還有任務(wù)到來就會采取任務(wù)拒絕策略,通常有以下四種策略:
ThreadPoolExecutor.AbortPolicy:丟棄任務(wù)并拋出RejectedExecutionException異常。 ThreadPoolExecutor.DiscardPolicy:也是丟棄任務(wù),但是不拋出異常。 ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務(wù),然后重新嘗試執(zhí)行任務(wù)(重復(fù)此過程) ThreadPoolExecutor.CallerRunsPolicy:由調(diào)用線程處理該任務(wù)當(dāng)Executor已經(jīng)關(guān)閉(即執(zhí)行了executorService.shutdown()方法后),并且Executor將有限邊界用于最大線程和工作隊列容量,且已經(jīng)飽和時,在方法execute()中提交的新任務(wù)將被拒絕.
在以上述情況下,execute 方法將調(diào)用其 RejectedExecutionHandler 的RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) 方法。
線程池默認(rèn)會采用的是defaultHandler策略。首先看defaultHandler的定義:
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy(); // 使用默認(rèn)的拒絕策略 //丟棄任務(wù)并拋出RejectedExecutionException異常。 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()); } }如下是一個測試任務(wù)的例子,下面編寫4個測試用例來測試。
class MyRunnable implements Runnable { private String name; public MyRunnable(String name) { this.name = name; } @Override public void run() { try { System.out.println(this.name + " is running."); Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } } }看一下其他拒絕策略的具體實現(xiàn)。
- 1.DiscardPolicy 示例(也是丟棄任務(wù),但是不拋出異常。)
線程池pool的”最大池大小”和”核心池大小”都為1(THREADS_SIZE),這意味著”線程池能同時運行的任務(wù)數(shù)量最大只能是1”。
線程池pool的阻塞隊列是ArrayBlockingQueue,ArrayBlockingQueue是一個有界的阻塞隊列,ArrayBlockingQueue的容量為1。這也意味著線程池的阻塞隊列只能有一個線程池阻塞等待。
根據(jù)”“中分析的execute()代碼可知:線程池中共運行了2個任務(wù)。第1個任務(wù)直接放到Worker中,通過線程去執(zhí)行;第2個任務(wù)放到阻塞隊列中等待。其他的任務(wù)都被丟棄了!
- 2.DiscardOldestPolicy 示例(丟棄隊列最前面的任務(wù),然后重新嘗試執(zhí)行任務(wù)(重復(fù)此過程))
運行結(jié)果:
task-0 is running. task-9 is running.將”線程池的拒絕策略”由DiscardPolicy修改為DiscardOldestPolicy之后,當(dāng)有任務(wù)添加到線程池被拒絕時,線程池會丟棄阻塞隊列中末尾的任務(wù),然后將被拒絕的任務(wù)添加到末尾。
- 3.AbortPolicy 示例(丟棄任務(wù)并拋出RejectedExecutionException異常。)
(某一次)運行結(jié)果:
java.util.concurrent.RejectedExecutionExceptionat java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1774)at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:768)at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:656)at AbortPolicyDemo.main(AbortPolicyDemo.java:27) task-0 is running. task-1 is running.將”線程池的拒絕策略”由DiscardPolicy修改為AbortPolicy之后,當(dāng)有任務(wù)添加到線程池被拒絕時,會拋出RejectedExecutionException。
- 4.CallerRunsPolicy 示例(由調(diào)用線程處理該任務(wù))
(某一次)運行結(jié)果:
task-2 is running. task-3 is running. task-4 is running. task-5 is running. task-6 is running. task-7 is running. task-8 is running. task-9 is running. task-0 is running. task-1 is running.將”線程池的拒絕策略”由DiscardPolicy修改為CallerRunsPolicy之后,當(dāng)有任務(wù)添加到線程池被拒絕時,線程池會將被拒絕的任務(wù)添加到”線程池正在運行的線程”中取運行。
參考來自http://blog.csdn.net/zhoufenqin/article/details/51012666
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Java线程池--拒绝策略RejectedExecutionHandler的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Boot 2.x多线程--
- 下一篇: MySQL日期及时间加减函数