线程池源码解读——回归基础

编程

线程池的好处: JDK提供的创建线程池: java 中创建线程的方式: 线程池源码解读: 记录的知识点:

线程池的好处:

  1. 降低资源的开销

  2. 提高响应速度

  3. 提高线程的可管理性

JDK提供的创建线程池:

  1. Executors.newCachedThreadPool():能够灵活回收线程,存在OOM的风险。

  2. Executors.newFixedThreadPool(5) :能控制并发,不能灵活回收线程。

  3. Executors.newScheduThreadPool(5):能够定时按周期执行任务,不能灵活回收线程。

  4. Executors.newSingleThreadExecutor():能保证任务按顺序执行,性能不好。

java 中创建线程的方式:

创建只有一种:new Thread,其他只是任务。

线程池源码解读:

  • 自定义线程池:

public ThreadPoolExecutor(int corePoolSize, 核心线程数

                        int maximumPoolSize,最大线程数

                        long keepAliveTime,存活时间

                        TimeUnit unit,存活时间单位

                        BlockingQueue<Runnable> workQueue,任务队列

                        ThreadFactory threadFactory,线程工厂

                        RejectedExecutionHandler handler) 拒绝策略

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; }

  • 线程池源码原理:

    public void execute(Runnable command) {

      if (command == null)

          throw new NullPointerException();

      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);

          else if (workerCountOf(recheck) == 0)

              addWorker(null, false);

      }

      else if (!addWorker(command, false))

          // 拒绝策略处理任务

          reject(command);

    }

    核心方法:addWorker

    private boolean addWorker(Runnable firstTask, boolean core) {

      // 标记

      retry:

      ...

      // 与最大线程池做比较

      wc >= (core ? corePoolSize : maximumPoolSize))

            return false;

      if (compareAndIncrementWorkerCount(c))

            break retry;

      ...

      boolean workerStarted = false;

      boolean workerAdded = false;

      Worker w = null;

      ...

      w = new Worker(firstTask);

      final Thread t = w.thread;

      // 重入锁控制线程安全

      final ReentrantLock mainLock = this.mainLock;

      mainLock.lock();

      if (workerAdded) {

          t.start();

          workerStarted = true;

      }

      mainLock.unlock();

      ...

      return workerStarted;

    }

  • 线程池源码原理图:

记录的知识点:

  • 线程池流程顺序:核心线程池执行任务,任务加入队列、最大线程池处理任务,拒绝策略。

  • 线程池中使用了队列,ReentrantLock

  • 线程池源码中else代码没有(代码风格可学习)

  • 线程池主要应用场景为优化。提升响应时间。

  • Fork/Join 并行执行任务

  • 美团技术相关线程池学习-推荐

从基础 到 框架 再到 基础。保持危机感。

以上是 线程池源码解读——回归基础 的全部内容, 来源链接: utcz.com/z/515189.html

回到顶部