[JUC source code] Thread pool: ThreadPoolExecutor (two) underlying structure analysis

Thread pool series:

Before the article starts, we must first understand why there is such a thing as a thread pool. Thread is a scarce resource. If it is not restricted, it will not only take up a lot of resources, but also affect the stability of the system. The thread pool can control the creation and stopping of threads, the number of threads, and other factors, so that threads can run in a controllable range. While ensuring the stable operation of the system, it also makes performance tuning more convenient. In addition, each time a request comes, because the creation of the thread has been completed, the task can be executed directly, which reduces the overhead of creating and destroying the thread each time, and improves the response speed.

OK, let's enter the main show, the source code...

ThreadPoolExecutor core inheritance relationship, member variables and main constructor:

public class ThreadPoolExecutor extends AbstractExecutorService {
    
    
    
    // ctl 线程池状态控制字段,由两部分组成:
    // int ctlOf(int rs, int wc) { return rs | wc; }
	private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    // 1:workerCount  wc 工作线程数,我们限制 workerCount 最大到(2^29)-1,大概 5 亿个线程
    private static final int COUNT_BITS = Integer.SIZE - 3;// 29
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;// =(2^29)-1=536870911
    // 2:runState rs 线程池的状态,提供了生命周期的控制,源码中有很多关于状态的校验,状态枚举如下:
    private static final int RUNNING    = -1 << COUNT_BITS;//536870912
    private static final int SHUTDOWN   =  0 << COUNT_BITS;//0
    private static final int STOP       =  1 << COUNT_BITS;//536870912
    private static final int TIDYING    =  2 << COUNT_BITS;//1073741824
    private static final int TERMINATED =  3 << COUNT_BITS;//1610612736

    
    // Worker 线程池中任务执行的最小单元
    private final class Worker extends AbstractQueuedSynchronizer implements Runnable{
    
    ...}
    
    
    // 任务队列,阻塞队列,来保持线程的存活周期
    // 注:这里使用阻塞队列而不是普通容器,是为了worker在取任务时借助它的线程调度能力
    //    比如当线程池中的线程空闲下来了,它就会在队列的另一端等待外部线程投递任务
    //    这里注意,因为将外部线程的任务放入任务队列调用的是offer方法,所以入队时不会出现外部线程阻塞
    private final BlockingQueue<Runnable> workQueue;
	// 工作线程集合,包含线程池中所有的工作线程
    private final HashSet<Worker> workers = new HashSet<Worker>();
    // 锁,大多数情况下是控制对 workers 的访问权限(如将新worker加入)
    private final ReentrantLock mainLock = new ReentrantLock();
    private final Condition termination = mainLock.newCondition();
    
   
    // 已完成任务的计数
    volatile long completedTasks;
    // 线程池最大容量
    private int largestPoolSize;
    // 已经完成的任务数
    private long completedTaskCount;
    
    //-----------------------------用户可控属性(volatile)-----------------------------
    // 可以使用 threadFactory 创建 thread
    // 创建失败一般不抛出异常,只有在 OutOfMemoryError 时候才会
    private volatile ThreadFactory threadFactory;
    // 线程空闲的最大时间
    private volatile long keepAliveTime;
    // coreSize,allowCoreThreadTimeOut决定是否回收
    private volatile int corePoolSize;
    // maxSize,除核心线程外,空闲就会回收
    private volatile int maximumPoolSize;
    // 饱和或者运行中拒绝任务的 handler 处理类
    private volatile RejectedExecutionHandler handler;
    
    // 默认的拒绝策略
    private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
    
    // 设置 true 的话,核心线程空闲 keepAliveTime 时间后,也会被回收
    // 需要调用allowCoreThreadTimeOut方法进行设置,默认false
    private volatile boolean allowCoreThreadTimeOut;
    
    //-------------------------------构造函数----------------------------------------
    // 构造函数的作用就是设置上面的volatile变量们
    // 注:前五参数个必有,theadFactory与rejected可以没有
    public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    
    ...}
}

Here are a few related parameters:

Thread pool status

  • RUNNING: can receive new tasks, and can also process tasks in the blocking queue
  • SHUTDOWN: Can not receive new tasks, but can process tasks in the blocking queue
  • STOP: Can not receive new tasks, do not process tasks in the blocking queue, and interrupt the tasks being processed
  • TIDYING: It belongs to the transitional phase. In this state, it means that all tasks have ended, the current thread pool has no valid threads, and the terminal method will be called
  • TERMINALED: termination status
    Insert picture description here

Rejection strategy

  • AbortPolicy (default): throw an exception
  • CallerRunsPolicy: do not use the thread pool, the main thread to execute
  • DiscardPolicy: directly discard the task
  • DiscardOldestPolicy: Discard the oldest task in the queue

Guess you like

Origin blog.csdn.net/weixin_43935927/article/details/113965321