jvm之线程池

java线程池实现继承关系

Executor==>ExecutorService-->AbstractExecutorService==>ThreadPoolExecutor
  • Executor-接口
    • execute,执行某个Runnable实现类
  • ExecutorService-接口,较Executor提供了更多的功能
    • submit,执行Callable实现类,返回值通过Future返回
  • AbstractExecutorService-线程池抽象类
    • 实现了submit方法
    • 在执行submit方法前会将Callable转为FutureTask类,然后调用execute方法执行
    • FutureTask是Runnable的实现类
    • 线程池基本都继承该抽象类

线程池实现类

ThreadPoolExecutor

  • 实现了execute方法,在该方法中判断核心线程数
    • 如果小于核心线程数,则通过addWorker新增核心线程执行该command
    • 如果小于核心线程数,则将command添加至任务队列中
    • 如果添加队列失败,则继续通过addWorker新增非核心线程
    • 如果新增线程失败,则执行拒绝策略
  • addWorker是添加线程的方法
    • 在该方法中会创建一个Worker实例,Worker是aqs的实现类
    • Worker构造方法中通过this.thread = getThreadFactory().newThread(this);维护一个线程及第一个task
    • 通过Worker获取到创建的thread,执行start方法,故会执行Worker的run方法
    • 在run中执行runWorker方法,在该方法中会从BlockingQueue中获取task循环执行
    • 如果BlockingQueue中为空,则会阻塞,直到有数据后返回
    • 获取到task,继续执行

ScheduledThreadPoolExecutor 任务定时执行器,继承自ThreadPoolExecutor

  • ScheduledThreadPoolExecutor的submit及execute方法执行的均为schedule方法
  • 在delayedExecute中将task封装为RunnableScheduledFuture调用delayedExecute方法
  • 在delayedExecute方法中会向super.getQueue()中添加该task
  • super.queue为ScheduledThreadPoolExecutor构造方法中调用父类ThreadPoolExecutor构造方法传入的DelayedWorkQueue
  • DelayedWorkQueue通过RunnableScheduledFuture<?>[]数组维护task执行顺序,在ThreadPoolExecutor 获取task时,如果未到时间则等待
  • ScheduledFutureTask中的heapIndex为该future在RunnableScheduledFuture<?>[]数组中的索引
  • 向DelayedWorkQueue添加task
    • 如果数据中已存在task,则在添加时,会依次比较执行时间,将新添加的task保存到对应索引值上
    • 如果将该task添加到 0 索引位置上,则立即唤醒因获取不到task而wait的线程执行该task
    • take方法收到信息后,继续执行,获取第一个task并return
    • 如果take方法未获取到,则直接await
    • 如果take方法获取到的未到时间,则通过available.awaitNanos(delay);修改delay时长
  • 总结ScheduledThreadPoolExecutor比ThreadPoolExecutor的区别是维护了一个DelayedWorkQueue

ForkJoinPool-分而治之线程池

ThreadFactory

用于创建thread,在newThread方法中可进行一些自定义的操作,如threadlocal赋值,自定义thread name,指定threadgroup ,设置thread stack size等

ThreadGroup

在创建thread时可以指定threadgroup,用于批量管控thread,比如可通过group.interrupt();打断所有的thread