JUC源码解析-线程池-ThreadPoolExecutor

本文详细解析了Java的ThreadPoolExecutor线程池的工作流程,包括线程池状态、任务提交、核心线程与最大线程的管理。同时,介绍了如何通过监控线程池的状态,如taskCount、completedTaskCount等,以及如何扩展线程池进行任务执行前后的监控。
摘要由CSDN通过智能技术生成

ThreadPoolExecutor

首先来看看线程池的主要工作流程图

 

 

接下来看看源码实现:

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;

    // Packing and unpacking ctl
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    private static int ctlOf(int rs, int wc) { return rs | wc; }

AtomicInteger的ctl变量,用低29位表示线程个数,高3位表示线程池状态;

  1. RUNNING :高三位:111,此时的线程池会接收任务,并处理阻塞队列中的任务;这里注意它其实是最小的
  2. SHUTDOWN:高三位:000,此时的线程池不会接收新的任务,但会处理阻塞队列中的任务。
  3. STOP:高三位:001,不接受新的任务,也不处理阻塞队列中的任务,而且中断正在执行的任务。
  4. TIDYING:010
  5. TERMINATED:011

我们使用Executor的execute(Runnable task)提交任务,但是它没有返回值,无法判断任务执行情况;而ExecutorService的submit(Callable task),返回Future,我们通过它来判断任务是否执行成功;

execute

        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            //到这里说明状态为Running,任务也已经加入队列,workerCountOf(recheck) == 0代表线程池里并没有线程,
            //addWorker(null, false),任务传null,意思是创建新线程来处理队列中的任务
            else if (workerCountOf(recheck) == 0) 
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
  1. workerCountOf(c)获取低29位,也就是线程数,如果小于核心线程数,则调用addWork方法创建线程执行任务;否则执行步骤2
  2. 若当前线程池状态是RUNNING,则将任务添加到阻塞队列workQueue.offer(command)非阻塞,执行步骤3,否则执行步骤4;
  3. 由于加入队列操作的耗时,所以加进队列后会对当前线程池状态再次进行判断,若不在是RUNNING,则从队列中删除任务,再调用handler处理任务;
  4. addWorker(command, false)创建线程执行任务,执行失败则调用handler处理任务;

addWork

    private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值