39 图解ThreadPoolExecutor的实现下
Diego38 57 1

1. 前言

上节我们对ThreadPoolExecutor的任务提交流程和停止线程池有了基本的了解。

本节我们深入到ThreadPoolExecutor内部运行和监控细节来一看究竟。

2. ThreadPoolExecutor的全景图

以下全景图包括提交任务、任务运行、future结果等待获取、通过future取消,运行监控等几部分,其中提交任务是面试中非常常见的考察点,所以上节已经详细梳理。 image

结合全景图我们分别对如上几个步骤进行分析

  • 提交任务 我们看左边thread1 ~ thread3,进行提交submit任务,而thread4通过execute执行任务,两种提交方式都会进入提交流程,新建线程或者进入队列。 thread1在提交任务时,线程数还未达到corePoolSize,于是未经过队列,直接创建线程执行。 thread2和thread3提交线程后进入队列,而由于队列满,thread3入队失败,进而触发线程池创建更多的线程来响应任务。 线程池中的线程数量大于corePoolSize时,并且空闲时间大于keepAliveTime,将会触发自动缩容。

  • 任务运行 提交任务的两种方式一种是submit,一种是execute。两者是不一样的,submit方法提交后,任务被修饰成FutureTask类型,FutureTask包装了设置任务结果、任务异常、阻塞等待结果等能力。Worker1中运行了FutureTask,无论是submit提交还是execute提交,Worker在每次执行时都会进行加锁。FutureTask有三种核心状态,分别为NORMAL,EXCEPTIONAL和CANCELLED,当正常执行完成状态为NORMAL,当执行过程中出现异常则是EXCEPTIONAL,如果任务被取消则是CANCELLED。 在执行结束后,会唤醒执行get操作的线程,FutureTask也是一种AQS,在JDK1.7是继承AQS来实现的,之后JDK1.8之后,完全内置了实现,但实际上和AQS原理相同,内部也是有一个等待队列。

thread4是使用execute执行,最终任务到Worker中,execute提交任务不会被FutureTask修饰,这样无法得到执行结果,也无法感知到运行异常,异常的任务会导致Worker数量减少,但内部维护的线程数也会相应减少,不会出现线程池泄露的情况发生。

  • Future结果获取 FutureTask是Future的实现,上图中thread7 ~ thread9 在等待同一个FutureTask的完成,由于FutureTask也是一种AQS,三个线程会进入一个等待队列,等待队列会维护在FutureTask内部。

  • Future任务取消 FutureTask任务取消,即简单的将FutureTask的状态修改为CANCELLED,操作期间不需要进入等待,线程池遇到取消的任务会直接忽略。

  • 运行监控 核心的监控方法有三种,

    • getCompletedTaskCount, 遍历worker累加每个worker完成的task数量
    • getActiveCount,获取所有活跃的worker的数量,内部是通过判断worker是否处于加锁状态来确认活跃的。
    • getTaskCount,获取队列内里和完成的所有的task的数量,即queue-TaskSize + getCompletedTaskCount

      3. ThreadPoolExecutor的监控

      线程池的配置决定着整个应用的性能状态,要对线程池配置调优,也离不开ThreadPoolExecutor内部运行状态的监控。ThreadPoolExecutor内置了多个监控方法: image

get操作中,有很多监控方法

  • getLargestPoolSize 是获取线程池运行后最大的线程数快照。
  • getCorePoolSize, getMaximumPoolSize, getThreadFactory都是获取配置信息,在构造函数一经传入,都不会变
  • getPoolSize 是获取当前运行的线程池数量,内部是通过mainLock来保证线程安全的
  • getCompletedTaskCount 、getActiveCount、getTaskCount和getPoolSize一样,都是通过mainLock来保证线程安全,因为获取整个线程池的信息,需要遍历所有的Worker进行叠加,前面讲过worker在运行每个任务前都需要加锁,判断worker是否加锁就能知道worker是否空闲,所以是有利于统计的。

    4. 总结

    image
预览图
评论区

索引目录