Skip to content

线程池流程图

关键属性

  • ctl

    使用高 3 位保存线程池运行状态,低 29 为保存运行线程数

  • workQueue

    工作队列,保存需要运行的线程

  • mainLock

    主锁,在修改一下核心属性是需要持有该锁

  • largestPoolSize

    达到的最大线程数量,访问需要持有 mainLock

  • completedTaskCount

    完成任务的计数器。访问需要持有 mainLock

  • threadFactory

    线程工厂

  • handler

    添加任务失败,或者强制结束线程是调用

  • keepAliveTime

    工作线程允许空闲时间

  • allowCoreThreadTimeOut

    是否允许核心线程超时,默认 false

  • corePoolSize

    核心线程数量

  • maximumPoolSize

    最大线程数量

常用方法

  • shutdown

    结束线程池,但会执行完已提交的任务。不会接收新任务。

  • shutdownNow

    结束线程池,不会执行队列中的任务。并对所有工作线程进行中断。

  • allowCoreThreadTimeOut

    设置是否允许核心线程超时关闭

  • getActiveCount

    获取工作线程数量

  • getLargestPoolSize

    获取最大的工作线程数量

  • getTaskCount

    获取执行的任务数量,包括执行中的。是一个近似值。

  • getCompletedTaskCount

    获取已完成的任务数量。不包含运行中的。也是一个近似值。

  • beforeExecute

    每一个任务执行前调用的方法,可以通过子类实现。

  • afterExecute

    每一个任务执行后调用的方法,可以通过子类实现。

  • prestartAllCoreThreads

    启动所有核心线程

  • prestartCoreThread

    启动一个核心线程

  • ensurePrestart

    prestartCoreThread一样,不过核心线程数为 0 是也会启动一个线程。

  • purge

    取消掉所有以结束的任务

ScheduledThreadPoolExecutor

定时调度的线程池,继承与ThreadPoolExecutor。通过重写submitexecute等方法,并实现私有的BlockingQueuejava.util.concurrent.ScheduledThreadPoolExecutor.DelayedWorkQueue。把所有的的任务都包装成java.util.concurrent.ScheduledThreadPoolExecutor.ScheduledFutureTask来进行统一管理。

ScheduledFutureTask

封装所有的任务,进行统一的调度。

主要属性
  • sequenceNumber:在创建任务是生成的序列号,在执行时间一致时来决定执行顺序
  • time:执行时间,用来进行排序,决定执行顺序。
  • period:周期。大于 0 时为固定速率,等于 0 时为非周期任务,小于 0 是为固定延迟执行。
  • heapIndex:在队列DelayedWorkQueue的索引,用来快速取消。
主要函数
  • compareTo:执行顺序的关键,通过对比timesequenceNumber进行比较。
  • getDelay:返回剩余的延迟,0 或负数则表示已经过去。
  • run:核心函数,如果是周期任务则在执行完后重新设置下次执行的时间,并把当前任务加入到队列中。

DelayedWorkQueue

一个私有的无界阻塞队列,针对 ScheduledThreadPool 进行特殊处理。主要表现在获取数据时通过ScheduledFutureTask#getDelay来处理。

主要属性
  • leader:下一个任务执行的线程。只有该线程是延时阻塞,其他线程都是无限期等待。在获取完任务后会唤醒一个等待的线程。
  • available:一个条件信号,在leader发生变更时会发出条件信号。
主要函数
  • take:获取任务,获取不到无限等待。在当前线程不用回收是,线程池通过该方法获取任务。
  • poll:获取任务,获取不到超时等待。在当前线程可以被回收是,通过该方法获取任务。
  • offer:添加任务。设置ScheduledFutureTask#heapIndex并唤醒一个线程获取任务

主要函数

  • decorateTask:可以通过子类来修改运行的任务。
  • delayedExecute:延时执行任务。
  • schedule:添加任务,把任务都包装成RunnableScheduledFuture放入到延时队列中。