ThreadPoolExecutor 源码

125 阅读5分钟

线程池的7个参数

  • int corePoolSize : 核心线程数
  • int maximumPoolSize :最大线程数
  • long keepAliveTime : 空闲时间
  • TimeUnit unit : 空闲时间单位
  • BlockingQueue : 阻塞队列
  • ThreadFactory threadFactory :线程工厂
  • RejectedExecutionHandler handler : 拒绝策略

    核心属性

//1、当前线程池状态 2、线程池中的线程数
//1、高三位是线程池状态  低29位是:线程池中的线程个数
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); 
//29 方便做位运算
private static final int COUNT_BITS = Integer.SIZE - 3;
//通过位运算得到最大容量
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
​
//- 线程池状态
//前三位都是1----正常接受任务
private static final int RUNNING    = -1 << COUNT_BITS;
//前三位都是000 ---不接受任务 ,内部还会处理任务
private static final int SHUTDOWN   =  0 << COUNT_BITS;
//前三位是001  ---不接受新任务 ,内部任务也不处理,中断正在执行的任务
private static final int STOP       =  1 << COUNT_BITS;
//前三位是010  --- 当前线程对即将 Game Over
private static final int TIDYING    =  2 << COUNT_BITS;
//前三位是011  --- 已Game Over
private static final int TERMINATED =  3 << COUNT_BITS;
//得到线程池状态
private static int runStateOf(int c)     { return c & ~CAPACITY; }
//当前线程池的线程数量
private static int workerCountOf(int c)  { return c & CAPACITY; }

image.png

线程池执行流程

image.png

ThreadPoolExecutor#execute方法

public void execute(Runnable command) {
  //健壮性校验
  if (command == null){
    throw new NullPointerException();
  }
​
  //拿到32位的bit
  int c = ctl.get();
  //工作线程数小于核心线程数
  if (workerCountOf(c) < corePoolSize) {
    //添加一个核心线程并把command作为此线程的第一任务
    if (addWorker(command, true)){
       return;
    }
    //添加失败 重新获取 ctl (并发问题)
    c = ctl.get();
  }
  //线程池是运行状态 && 把任务添加到缓存队列
  if (isRunning(c) && workQueue.offer(command)) {
    //获取ctl (并发问题)
    int recheck = ctl.get();
    //线程池 不是运行状态 则移除任务 
    if (! isRunning(recheck) && remove(command)){
      //执行拒绝策略
      reject(command);
      //工作线程数为零(并发)
    }else if (workerCountOf(recheck) == 0){
      //添加非核心线程
      addWorker(null, false);
    }
    //缓存队列满了,添加非核心线程,并把任务作为线程的第一个任务执行
  }else if (!addWorker(command, false)){
    //执行拒绝策略
    reject(command);
  }
}

ThreadPoolExecutor#addWorker

private boolean addWorker(Runnable firstTask, boolean core) {
  retry:
  for (;;) {
    //获取ctl 32位
    int c = ctl.get();
    //从32位获取线程池状态
    int rs = runStateOf(c);
    // 非RUNNING &&
    if (rs >= SHUTDOWN &&
        //线程池状态不是 SHUTDOWN || firstTask 不是null || 队列是空
        (rs != SHUTDOWN || firstTask != null &&  workQueue.isEmpty())){
      // 构建工作线程失败
      return false;
      //总结下 : 线程状态非RUNNING 并且 (不是SHUTDOWN(不会再自行任务了)||firstTask !=null (不是为了创建线程) || 待执行对队列为空 。 
      // 最后 线程状态 > SHUTDOWN  || 是 SHUTDOWN  但是没有待执行任务 ,或提交任务 返回false
    }
    //线程池为running 状态
    for (;;) {
      //获取工作线程数
      int wc = workerCountOf(c);
      //工作线程个数 >= 最大线程数 || 大于核心线程数或最大线程数 返回 false
      if (wc >= CAPACITY ||
          wc >= (core ? corePoolSize : maximumPoolSize))
        return false;
      //ctl 自增1失败
      if (compareAndIncrementWorkerCount(c)){
        //回跳到 retry
         break retry;
      }
      //获取最新的ctl 
      c = ctl.get();  
      //线程池状态发生变化 (乐观锁)
      if (runStateOf(c) != rs)
        //回到 retry CAS failed due to workerCount change; retry inner loop
        continue retry;
    }
  }
  //以上 给线程数+1
  //worker开始 = false
  boolean workerStarted = false;
  //worker添加 = false
  boolean workerAdded = false;
  Worker w = null;
  try {
    //创建worker
    w = new Worker(firstTask);
    //从worker里获取线程T
    final Thread t = w.thread;
    if (t != null) {
      //获取锁对象
      final ReentrantLock mainLock = this.mainLock;
      //加锁 避免添加任务是 其他地方 干掉线程池。
      mainLock.lock();
      try {
        // Recheck while holding lock.
        // Back out on ThreadFactory failure or if
        // shut down before lock acquired.
        //获取线程池状态
        int rs = runStateOf(ctl.get());
        //线程池状态是RUNNING 或 是 SHUTDOWN && firstTask 是null
        if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) {
          //如果线程是运行状态抛异常
          if (t.isAlive()){
            throw new IllegalThreadStateException();
          }
          //workers 添加到队列汇总
          workers.add(w);
          //获取workers 队列大小 > 之前记录的最大的线程数 替换下
          int s = workers.size();
          if (s > largestPoolSize){
            largestPoolSize = s;
          }
          workerAdded = true;
        }
      } finally {
        mainLock.unlock();
      }
      if (workerAdded) {
        //线程启动
        t.start();
        workerStarted = true;
      }
    }
  } finally {
    if (! workerStarted){
      //回滚
      addWorkerFailed(w);
    }
  }
  //返回结果
  return workerStarted;
}

worker

Worker#run

public void run() {
  runWorker(this);
}

ThreadPoolExecutor#runWorker

final void runWorker(Worker w) {
  //获取当前线程
  Thread wt = Thread.currentThread();
  //获取 Task任务
  Runnable task = w.firstTask;
  w.firstTask = null;
  w.unlock(); // allow interrupts
  boolean completedAbruptly = true;
  try {
    //有要执行的任务(Task) ,没有就阻塞
    while (task != null || (task = getTask()) != null) {
      //任务锁定
      w.lock();
      //大于等于STOP || 
      if ((runStateAtLeast(ctl.get(), STOP) ||
           (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted())
        wt.interrupt();
      try {
        beforeExecute(wt, task);
        Throwable thrown = null;
        try {
          task.run();
        } catch (RuntimeException x) {
          thrown = x; throw x;
        } catch (Error x) {
          thrown = x; throw x;
        } catch (Throwable x) {
          thrown = x; throw new Error(x);
        } finally {
          afterExecute(task, thrown);
        }
      } finally {
        task = null;
        //处理任务数+1
        w.completedTasks++;
        w.unlock();
      }
    }
    completedAbruptly = false;
  } finally {
    processWorkerExit(w, completedAbruptly);
  }
}

ThreadPoolExecutor#getTask

private Runnable getTask() {
  boolean timedOut = false; // Did the last poll() time out?
​
  for (;;) {
    //======================判断状态
    //获取ctl值
    int c = ctl.get();
    //获取线程池运行状态
    int rs = runStateOf(c);
​
    // 线程池状态不是RUNNING && (rs >= STOP || workQueue.isEmpty())
    if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
      //ctl数量减1
      decrementWorkerCount();
      //返回null 线程会结束
      return null;
    }
    //====================判断线程数量
    //获取工作线程数量
    int wc = workerCountOf(c);
​
    //线程等待超时||工作线程数>核心线程数  allowCoreThreadTimeOut---》允许核心线程超时么 一版是false
    boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
    //工作线程大于最大线程 || 工作线程数大于核心线程数 并且当前线程超时 ||工作线程数大于1 或则 工作队列为空
    if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) {
      //当前线程数减1
      if (compareAndDecrementWorkerCount(c)){
        //移除当前线程
        return null;
      }
      continue;
    }
    //===================取任务
    try {
      //获取task数据 ?阻塞一定时间拿任务 :一直阻塞
      Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take();
      if (r != null){
        return r;
      }
      //是否超时
      timedOut = true;
    } catch (InterruptedException retry) {
      timedOut = false;
    }
  }
}

ThreadPoolExecutor#processWorkerExit

private void processWorkerExit(Worker w, boolean completedAbruptly) {
        // completedAbruptly 当前线程是否执行完成 默认为true 执行完成为false
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();
​
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
          //移除worker
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }
        //尝试
        tryTerminate();
        //获取ctl
        int c = ctl.get();
        //线程池状态为 RUNNING || SHUTDOWN 时 
        if (runStateLessThan(c, STOP)) {
            if (!completedAbruptly) {
                // 取最小线程数 ,允许核心线程超时 min=0 否则 为核心线程数
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                //如果min==0 并且工作队队列不为空 最小值等于1
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                //工作线程数大于等于 min return 返回
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
          //创建非核心线程
            addWorker(null, false);
        }
    }

参考

juejin.cn/post/684490…

www.bilibili.com/video/BV124…
Java线程池实现原理及其在美团业务中的实践 动态线程池思想学习与实践