日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java线程池--拒绝策略RejectedExecutionHandler

發布時間:2025/1/21 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线程池--拒绝策略RejectedExecutionHandler 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

當線程池的任務緩存隊列已滿并且線程池中的線程數目達到maximumPoolSize,如果還有任務到來就會采取任務拒絕策略,通常有以下四種策略:

當線程池的任務緩存隊列已滿并且線程池中的線程數目達到maximumPoolSize,如果還有任務到來就會采取任務拒絕策略,通常有以下四種策略:

ThreadPoolExecutor.AbortPolicy:丟棄任務并拋出RejectedExecutionException異常。 ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,但是不拋出異常。 ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務,然后重新嘗試執行任務(重復此過程) ThreadPoolExecutor.CallerRunsPolicy:由調用線程處理該任務

當Executor已經關閉(即執行了executorService.shutdown()方法后),并且Executor將有限邊界用于最大線程和工作隊列容量,且已經飽和時,在方法execute()中提交的新任務將被拒絕.
在以上述情況下,execute 方法將調用其 RejectedExecutionHandler 的RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) 方法。

線程池默認會采用的是defaultHandler策略。首先看defaultHandler的定義:

private static final RejectedExecutionHandler defaultHandler = new AbortPolicy(); // 使用默認的拒絕策略 //丟棄任務并拋出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()); } }

如下是一個測試任務的例子,下面編寫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(); } } }

看一下其他拒絕策略的具體實現。

  • 1.DiscardPolicy 示例(也是丟棄任務,但是不拋出異常。)
public class DiscardPolicyDemo { private static final int THREADS_SIZE = 1; private static final int CAPACITY = 1; public static void main(String[] args) throws Exception { // 創建線程池。線程池的"最大池大小"和"核心池大小"都為1(THREADS_SIZE),"線程池"的阻塞隊列容量為1(CAPACITY)。 ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(CAPACITY)); // 設置線程池的拒絕策略為"丟棄" pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); // 新建10個任務,并將它們添加到線程池中。 for (int i = 0; i < 10; i++) { Runnable myrun = new MyRunnable("task-"+i); pool.execute(myrun); } // 關閉線程池 pool.shutdown(); } }

線程池pool的”最大池大小”和”核心池大小”都為1(THREADS_SIZE),這意味著”線程池能同時運行的任務數量最大只能是1”。
線程池pool的阻塞隊列是ArrayBlockingQueue,ArrayBlockingQueue是一個有界的阻塞隊列,ArrayBlockingQueue的容量為1。這也意味著線程池的阻塞隊列只能有一個線程池阻塞等待。   
根據”“中分析的execute()代碼可知:線程池中共運行了2個任務。第1個任務直接放到Worker中,通過線程去執行;第2個任務放到阻塞隊列中等待。其他的任務都被丟棄了!

  • 2.DiscardOldestPolicy 示例(丟棄隊列最前面的任務,然后重新嘗試執行任務(重復此過程))
public class DiscardOldestPolicyDemo { private static final int THREADS_SIZE = 1; private static final int CAPACITY = 1; public static void main(String[] args) throws Exception { // 創建線程池。線程池的"最大池大小"和"核心池大小"都為1(THREADS_SIZE),"線程池"的阻塞隊列容量為1(CAPACITY)。 ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(CAPACITY)); // 設置線程池的拒絕策略為"DiscardOldestPolicy" pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy()); // 新建10個任務,并將它們添加到線程池中。 for (int i = 0; i < 10; i++) { Runnable myrun = new MyRunnable("task-"+i); pool.execute(myrun); } // 關閉線程池 pool.shutdown(); } }

運行結果:

task-0 is running. task-9 is running.

將”線程池的拒絕策略”由DiscardPolicy修改為DiscardOldestPolicy之后,當有任務添加到線程池被拒絕時,線程池會丟棄阻塞隊列中末尾的任務,然后將被拒絕的任務添加到末尾。

  • 3.AbortPolicy 示例(丟棄任務并拋出RejectedExecutionException異常。)
public class AbortPolicyDemo { private static final int THREADS_SIZE = 1; private static final int CAPACITY = 1; public static void main(String[] args) throws Exception { // 創建線程池。線程池的"最大池大小"和"核心池大小"都為1(THREADS_SIZE),"線程池"的阻塞隊列容量為1(CAPACITY)。 ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(CAPACITY)); // 設置線程池的拒絕策略為"拋出異常" pool.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); try { // 新建10個任務,并將它們添加到線程池中。 for (int i = 0; i < 10; i++) { Runnable myrun = new MyRunnable("task-"+i); pool.execute(myrun); } } catch (RejectedExecutionException e) { e.printStackTrace(); // 關閉線程池 pool.shutdown(); } } }

(某一次)運行結果:

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之后,當有任務添加到線程池被拒絕時,會拋出RejectedExecutionException。

  • 4.CallerRunsPolicy 示例(由調用線程處理該任務)
public class CallerRunsPolicyDemo { private static final int THREADS_SIZE = 1; private static final int CAPACITY = 1; public static void main(String[] args) throws Exception { // 創建線程池。線程池的"最大池大小"和"核心池大小"都為1(THREADS_SIZE),"線程池"的阻塞隊列容量為1(CAPACITY)。 ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(CAPACITY)); // 設置線程池的拒絕策略為"CallerRunsPolicy" pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 新建10個任務,并將它們添加到線程池中。 for (int i = 0; i < 10; i++) { Runnable myrun = new MyRunnable("task-"+i); pool.execute(myrun); } // 關閉線程池 pool.shutdown(); } }

(某一次)運行結果:

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之后,當有任務添加到線程池被拒絕時,線程池會將被拒絕的任務添加到”線程池正在運行的線程”中取運行。

參考來自http://blog.csdn.net/zhoufenqin/article/details/51012666

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的Java线程池--拒绝策略RejectedExecutionHandler的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。