线程池系列之CallerRunsPolicy()拒绝策略

11,793 阅读2分钟

1.背景

学习线程池相关知识时,我们都知道线程池的拒绝策略有四种,其中有一种为CallerRunsPolicy()策略,查阅过很多知识,说法不一,因此本文通过实际代码测试详解CallerRunsPolicy()拒绝策略

2.CallerRunsPolicy拒绝策略的定义

CallerRunsPolicy类的注释是这样描述的

A handler for rejected tasks that runs the rejected task directly in the calling thread of the execute method, unless the executor has been shut down, in which case the task is discarded.

简单翻译过来就是对于被拒绝的任务,由调用 execute method方法的线程来执行

怎么理解呢?大家看下面代码

1.创建了一个线程,并且打印出了线程的名字

2.线程中定义了核心线程数为2的线程池,一共有7个任务要执行,其中2个任务创建线程执行去了,3个任务放入了任务队列

import java.util.concurrent.*;

/**
 * @author linsanity
 * @date 2021-07-07 17:21
 * @desc
 */
class MyTask implements Runnable {
    private String id;

    public MyTask(String id) {
        this.id = id;
    }

    public void run() {
        System.out.println(id+"线程名"+Thread.currentThread().getName());
    }
}

public class RejectPolicy {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                ExecutorService es = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS,
                        new ArrayBlockingQueue<Runnable>(3), Executors.defaultThreadFactory(),
                        new ThreadPoolExecutor.CallerRunsPolicy());
                MyTask t1 = new MyTask("id:1");
                MyTask t2 = new MyTask("id:2");
                MyTask t3 = new MyTask("id:3");
                MyTask t4 = new MyTask("id:4");
                MyTask t5 = new MyTask("id:5");
                MyTask t6 = new MyTask("id:6");
                MyTask t7 = new MyTask("id:7");

                es.execute(t1);
                es.execute(t2);
                es.execute(t3);
                es.execute(t4);
                es.execute(t5);
                es.execute(t6);
                es.execute(t7);
            }
        });

        System.out.println("new Thread得到的线程名:"+thread.getName());
        thread.start();
    }
}

输出如下

new Thread得到的线程名:Thread-0
id:6线程名Thread-0
id:7线程名Thread-0
id:1线程名pool-1-thread-1
id:3线程名pool-1-thread-1
id:2线程名pool-1-thread-2
id:4线程名pool-1-thread-1
id:5线程名pool-1-thread-2

可以看到任务6和任务7的执行线程并非是线程池中的线程执行的

3.结论

CallerRunsPolicy()拒绝策略是指被拒绝的任务,由[调用execute方法的线程]来执行被拒绝的任务(哪个线程调用了execute方法,那么这个线程来执行被拒绝的任务)