I、UML

II、依赖

III、运行流程

IV、生命周期

run statedesc
RUNNING能接管新工作,且能解决队列中工作
SHUTDOWN不能接管新工作,但能持续解决队列中工作
STOP新工作和队列中工作都不能解决,会中断正在解决工作的线程
TIDYING所有工作已终止
TERMINATEDterminated()之后的状态

V、任务调度

1、首先检测线程池运行状态,如果不是RUNNING,则间接回绝,线程池要保障在RUNNING的状态下执行工作。
2、如果workerCount < corePoolSize,则创立并启动一个线程来执行新提交的工作。
3、如果workerCount >= corePoolSize,且线程池内的阻塞队列未满,则将工作增加到该阻塞队列中。
4、如果workerCount >= corePoolSize && workerCount < maximumPoolSize,且线程池内的阻塞队列已满,则创立并启动一个线程来执行新提交的工作。
5、如果workerCount >= maximumPoolSize,并且线程池内的阻塞队列已满, 则依据回绝策略来解决该工作, 默认的解决形式是间接抛异样。

VI、Worker


1、工作是 Runnable(外部变量名叫 task 或 command),线程是 Worker。
2、Worker持有一个线程thread
3、Worker是通过继承AQS,应用AQS来实现独占锁这个性能。没有应用可重入锁ReentrantLock,而是应用AQS,为的就是实现不可重入的个性去反馈线程当初的执行状态。
——lock办法一旦获取了独占锁,示意以后线程正在执行工作中。
——如果正在执行工作,则不应该中断线程。
——如果该线程当初不是独占锁的状态,也就是闲暇的状态,阐明它没有在解决工作,这时能够对该线程进行中断。
——线程池在执行shutdown办法或tryTerminate办法时会调用interruptIdleWorkers办法来中断闲暇的线程,interruptIdleWorkers办法会应用tryLock办法来判断线程池中的线程是否是闲暇状态;如果线程是闲暇状态则能够平安回收。
4、执行工作流程

VII、须要关注和验证的几个重要知识点

1、线程池初始化线程数是可动静调整的。调小时工作将从新进入for循环。验证调大和调小时工作是否有影响。2、线程池一方面防止了解决工作时创立销毁线程开销的代价,另一方面防止了线程数量收缩导致的过分调度问题,保障了对内核的充分利用。创立销毁线程的开销、调度线程的开销。怎么验证这两种开销??? 3、设置的线程数过多可能还会引发线程上下文切换频繁的问题,也会升高解决工作的速度,升高吞吐量???还是怎么验证开销???4、最大外围数设置偏小,大量抛出RejectedExecutionException,触发接口降级条件。就是说是一种动静降级的计划。5、队列设置过长,最大线程数设置生效,导致申请数量减少时,大量工作沉积在队列中,工作执行工夫过长。嵌套的线程池,会不会呈现第一层的工作正在执行,与之关联的第二层工作正在期待,从而导致响应工夫长???

VIII、参考文章:

https://www.javadoop.com/post/java-thread-poolhttps://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html