线程池ExecutorService的4种拒绝策略

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,执行后面的任务,不抛出异常。 

ThreadPoolExecutor.CallerRunsPolicy:由调用线程池的线程(比如main线程)处理该任务 ,不抛出异常。 

正常实例:(默认的拒绝策略是: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(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(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 MyTask@27082746 rejected from java.util.concurrent.ThreadPoolExecutor@66133adc[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

你可能感兴趣的:(Java)