java线程池之四种拒绝策略

java线程池的四种拒绝策略

ThreadPoolExcutor中有四个内部类实现了线程池的拒绝策略。当然我们也可以自己定义,这里讲解一下这四个已经实现的拒绝策略。

什么情况下会拒绝新的任务

在什么情况下,线程池会拒绝新提交的任务呢。
java线程池之四种拒绝策略_第1张图片
在ThreadPoolExcutor的构造方法中,有这几个参数,参数的意义请参考:https://baijiahao.baidu.com/s?id=1637828094805085849&wfr=spider&for=pc
当maximumPoolSize和workQueue达到最大时,线程池会拒绝新的任务的提交

演示代码

public class ThreadPoolDemo {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,1,20,
                TimeUnit.MINUTES, new ArrayBlockingQueue<>(1),new ThreadPoolExecutor.AbortPolicy());

        for (int i = 0; i < 3; i++) {
            final int temp = i;
            threadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(4000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "完成" + temp);
                }
            });
        }

    }
}

这里我们创建了线程池的核心线程数只有1,最大线程数也只有1,工作队列也只有1,下面我们提交了三个任务。当第一个任务提交时,此时会创建一个新的线程,当第二个任务提交时,此时因为线程池中的线程数==核心线程数,且工作队列未满,任务2加入工作队列。当第三个任务到达时,因为线程池中的线程数等于核心线程数,且工作队列以及满了,同时,线程池中的最大线程数也已经到达了,所以任务3将被拒绝。
这里我们先演示AbortPolicy。

AbortPolicy

这个拒绝策略当新的任务被拒绝时,会跑出一个异常
java线程池之四种拒绝策略_第2张图片
运行结果如下:
在这里插入图片描述
这里我们看到,新提交的任务没有运行,并且抛出了一个异常

DiscardPolicy

这个拒绝策略将会悄悄的忽略掉被拒绝的任务,也不会抛出异常
java线程池之四种拒绝策略_第3张图片
运行结果:
java线程池之四种拒绝策略_第4张图片
既没有抛出异常,也没有运行任务

CallerRunsPolicy

这个拒绝策略将执行该任务,但是有提交者自己执行
java线程池之四种拒绝策略_第5张图片
运行结果:
java线程池之四种拒绝策略_第6张图片
这里虽然执行了任务2,但是该任务所执行的线程是在main(即它的提交者)

DiscardOldestPolicy

这个拒绝策略将会把最先进入工作队列的任务出队,为新的任务腾出位置
java线程池之四种拒绝策略_第7张图片
运行结果:
java线程池之四种拒绝策略_第8张图片
这里可以看到,最先进入工作队列的任务1被出队了。

你可能感兴趣的:(java,java,多线程,队列,并发编程)