執行緒池ExecutorService的4種拒絕策略
ThreadPoolExecutor.AbortPolicy:丟棄任務並丟擲RejectedExecutionException異常。
ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,但是不丟擲異常。
ThreadPoolExecutor.DiscardOldestPolicy:丟棄佇列最前面的任務,執行後面的任務
ThreadPoolExecutor.CallerRunsPolicy:由呼叫執行緒處理該任務
正常例項:(預設的拒絕策略是:AbortPolicy)
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class Main { public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5)); for (int i = 0; i < 15; i++) { MyTask myTask = new MyTask(i); executor.execute(myTask); System.out.println("執行緒池中執行緒數目:" + executor.getPoolSize() + ",佇列中等待執行的任務數目:" + executor.getQueue().size() + ",已執行完的任務數目:" + executor.getCompletedTaskCount()); } executor.shutdown(); } } class MyTask implements Runnable { private int taskNum; public MyTask(int num) { this.taskNum = num; } @Override public void run() { System.out.println("執行緒名稱:" + Thread.currentThread().getName() + ",正在執行task " + taskNum); try { Thread.currentThread().sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("task " + taskNum + "執行完畢"); } }
執行緒名稱:pool-1-thread-1,正在執行task 0
執行緒池中執行緒數目:1,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:2,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:3,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:4,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒名稱:pool-1-thread-2,正在執行task 1
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:1,已執行完的任務數目:0
執行緒名稱:pool-1-thread-3,正在執行task 2
執行緒名稱:pool-1-thread-5,正在執行task 4
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:2,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:3,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:4,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:6,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:7,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-6,正在執行task 10
執行緒池中執行緒數目:8,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-7,正在執行task 11
執行緒池中執行緒數目:9,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-9,正在執行task 13
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-10,正在執行task 14
執行緒名稱:pool-1-thread-4,正在執行task 3
執行緒名稱:pool-1-thread-8,正在執行task 12
task 0執行完畢
執行緒名稱:pool-1-thread-1,正在執行task 5
task 4執行完畢
task 1執行完畢
task 2執行完畢
執行緒名稱:pool-1-thread-2,正在執行task 7
執行緒名稱:pool-1-thread-5,正在執行task 6
執行緒名稱:pool-1-thread-3,正在執行task 8
task 11執行完畢
task 10執行完畢
執行緒名稱:pool-1-thread-7,正在執行task 9
task 13執行完畢
task 12執行完畢
task 3執行完畢
task 14執行完畢
task 5執行完畢
task 7執行完畢
task 6執行完畢
task 9執行完畢
task 8執行完畢
----後面把任務數設定為20
使用AbortPolicy:(只執行前15個任務,後面的丟棄且丟擲異常)
執行緒名稱:pool-1-thread-1,正在執行task 0import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class Main { public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5), new ThreadPoolExecutor.AbortPolicy()); for (int i = 0; i < 20; i++) { MyTask myTask = new MyTask(i); executor.execute(myTask); System.out.println("執行緒池中執行緒數目:" + executor.getPoolSize() + ",佇列中等待執行的任務數目:" + executor.getQueue().size() + ",已執行完的任務數目:" + executor.getCompletedTaskCount()); } executor.shutdown(); } } class MyTask implements Runnable { private int taskNum; public MyTask(int num) { this.taskNum = num; } @Override public void run() { System.out.println("執行緒名稱:" + Thread.currentThread().getName() + ",正在執行task " + taskNum); try { Thread.currentThread().sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("task " + taskNum + "執行完畢"); } }
執行緒池中執行緒數目:1,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:2,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒名稱:pool-1-thread-2,正在執行task 1
執行緒池中執行緒數目:3,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒名稱:pool-1-thread-3,正在執行task 2
執行緒池中執行緒數目:4,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒名稱:pool-1-thread-4,正在執行task 3
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:1,已執行完的任務數目:0
執行緒名稱:pool-1-thread-5,正在執行task 4
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:2,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:3,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:4,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:6,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-6,正在執行task 10
執行緒池中執行緒數目:7,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:8,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-7,正在執行task 11
執行緒名稱:pool-1-thread-8,正在執行task 12
執行緒池中執行緒數目:9,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-9,正在執行task 13
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-10,正在執行task 14
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task [email protected] rejected from [email protected][Running, pool size = 10, active threads = 10, queued tasks = 5, 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 Main.main(Main.java:13)
task 0執行完畢
task 2執行完畢
執行緒名稱:pool-1-thread-1,正在執行task 5
task 1執行完畢
執行緒名稱:pool-1-thread-2,正在執行task 7
執行緒名稱:pool-1-thread-3,正在執行task 6
task 4執行完畢
task 10執行完畢
task 3執行完畢
執行緒名稱:pool-1-thread-5,正在執行task 8
執行緒名稱:pool-1-thread-6,正在執行task 9
task 12執行完畢
task 11執行完畢
task 13執行完畢
task 14執行完畢
task 5執行完畢
task 6執行完畢
task 7執行完畢
task 8執行完畢
task 9執行完畢
使用DiscardPolicy:(只執行前15個任務,後面的丟棄不丟擲異常)
執行緒池中執行緒數目:1,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:2,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:3,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:4,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:1,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:2,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:3,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:4,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-2,正在執行task 1
執行緒池中執行緒數目:6,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-3,正在執行task 2
執行緒池中執行緒數目:7,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:8,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:9,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-7,正在執行task 11
執行緒名稱:pool-1-thread-6,正在執行task 10
執行緒名稱:pool-1-thread-8,正在執行task 12
執行緒名稱:pool-1-thread-4,正在執行task 3
執行緒名稱:pool-1-thread-10,正在執行task 14
執行緒名稱:pool-1-thread-1,正在執行task 0
執行緒名稱:pool-1-thread-5,正在執行task 4
執行緒名稱:pool-1-thread-9,正在執行task 13
task 1執行完畢
task 2執行完畢
執行緒名稱:pool-1-thread-2,正在執行task 5
執行緒名稱:pool-1-thread-3,正在執行task 6
task 11執行完畢
執行緒名稱:pool-1-thread-7,正在執行task 7
task 10執行完畢
執行緒名稱:pool-1-thread-6,正在執行task 8
task 12執行完畢
執行緒名稱:pool-1-thread-8,正在執行task 9
task 3執行完畢
task 14執行完畢
task 13執行完畢
task 0執行完畢
task 4執行完畢
task 5執行完畢
task 6執行完畢
task 7執行完畢
task 8執行完畢
task 9執行完畢
使用DiscardOldestPolicy:(發現任務5,6,7,8,9被拋棄)
執行緒名稱:pool-1-thread-1,正在執行task 0
執行緒池中執行緒數目:1,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:2,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒名稱:pool-1-thread-2,正在執行task 1
執行緒池中執行緒數目:3,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒名稱:pool-1-thread-3,正在執行task 2
執行緒池中執行緒數目:4,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒名稱:pool-1-thread-4,正在執行task 3
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:1,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:2,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:3,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:4,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:6,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-6,正在執行task 10
執行緒池中執行緒數目:7,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:8,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-8,正在執行task 12
執行緒池中執行緒數目:9,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-7,正在執行task 11
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:pool-1-thread-10,正在執行task 14
執行緒名稱:pool-1-thread-5,正在執行task 4
執行緒名稱:pool-1-thread-9,正在執行task 13
task 0執行完畢
執行緒名稱:pool-1-thread-1,正在執行task 15
task 3執行完畢
task 1執行完畢
執行緒名稱:pool-1-thread-2,正在執行task 17
task 2執行完畢
執行緒名稱:pool-1-thread-4,正在執行task 16
執行緒名稱:pool-1-thread-3,正在執行task 18
task 10執行完畢
執行緒名稱:pool-1-thread-6,正在執行task 19
task 11執行完畢
task 12執行完畢
task 14執行完畢
task 4執行完畢
task 13執行完畢
task 15執行完畢
task 16執行完畢
task 17執行完畢
task 18執行完畢
task 19執行完畢
使用CallerRunsPolicy:(main執行緒是執行緒池的呼叫者,main執行緒參與執行任務)
執行緒池中執行緒數目:1,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:2,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒名稱:pool-1-thread-1,正在執行task 0
執行緒池中執行緒數目:3,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:4,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:0,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:1,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:2,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:3,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:4,已執行完的任務數目:0
執行緒池中執行緒數目:5,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:6,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:7,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:8,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:9,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:0
執行緒名稱:main,正在執行task 15
執行緒名稱:pool-1-thread-3,正在執行task 2
執行緒名稱:pool-1-thread-7,正在執行task 11
執行緒名稱:pool-1-thread-5,正在執行task 4
執行緒名稱:pool-1-thread-9,正在執行task 13
執行緒名稱:pool-1-thread-2,正在執行task 1
執行緒名稱:pool-1-thread-6,正在執行task 10
執行緒名稱:pool-1-thread-10,正在執行task 14
執行緒名稱:pool-1-thread-4,正在執行task 3
執行緒名稱:pool-1-thread-8,正在執行task 12
task 0執行完畢
執行緒名稱:pool-1-thread-1,正在執行task 5
task 15執行完畢
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:4,已執行完的任務數目:1
執行緒池中執行緒數目:10,佇列中等待執行的任務數目:5,已執行完的任務數目:1
執行緒名稱:main,正在執行task 17
task 2執行完畢
執行緒名稱:pool-1-thread-3,正在執行task 6
task 11執行完畢
執行緒名稱:pool-1-thread-7,正在執行task 7
task 1執行完畢
task 4執行完畢
task 13執行完畢
執行緒名稱:pool-1-thread-2,正在執行task 8
執行緒名稱:pool-1-thread-5,正在執行task 16
執行緒名稱:pool-1-thread-9,正在執行task 9
task 14執行完畢
task 10執行完畢
task 12執行完畢
task 3執行完畢
task 5執行完畢
task 17執行完畢
執行緒池中執行緒數目:6,佇列中等待執行的任務數目:0,已執行完的任務數目:11
執行緒池中執行緒數目:6,佇列中等待執行的任務數目:1,已執行完的任務數目:11
執行緒名稱:pool-1-thread-1,正在執行task 18
執行緒池中執行緒數目:6,佇列中等待執行的任務數目:1,已執行完的任務數目:11
task 6執行完畢
執行緒名稱:pool-1-thread-3,正在執行task 19
task 7執行完畢
task 9執行完畢
task 16執行完畢
task 8執行完畢
task 18執行完畢
task 19執行完畢
參考:下面兩篇文章寫的都很好
https://www.cnblogs.com/dolphin0520/p/3932921.html Java併發程式設計:執行緒池的使用
https://blog.csdn.net/lmj623565791/article/details/27250059 Java併發專題 帶返回結果的批量任務執行 CompletionService ExecutorService.invokeAll