1. 程式人生 > >執行緒池ExecutorService的4種拒絕策略

執行緒池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個任務,後面的丟棄且丟擲異常)

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), 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 + "執行完畢");
    }
}
執行緒名稱: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
執行緒名稱: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