java | ThreadPoolExecutor 用法
source link: https://benpaodewoniu.github.io/2023/01/01/java156/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
线程池状态
ThreadPoolExecutor 使用 int 的高 3 位来表示线程池的状态,低 29 为表示线程池数量。「之所以以一个 int 来记录两个信息,而不是用两个 int 记录,是因为,使用一个 int 可以用 cas 原子操作进行赋值」
状态名 | 高3位 | 接收新任务 | 处理阻塞队列任务 | 说明 |
---|---|---|---|---|
RUNNING | 111 | Y | Y | |
SHUTDOWN | 000 | N | Y | 不会接收新任务,但会处理阻塞队列剩余任务 |
STOP | 001 | N | N | 会终端正在执行的任务,并抛弃阻塞队列的任务 |
TIDYING | 010 | - | - | 任务全部执行完毕,活动线程为 0 即将进入终结 |
TERMINATED | 011 | - | - | 终结状态 |
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize
- 核心线程数目「最多保留的线程数」
maximumPoolSize
- 最大线程数目
- 救急线程数等于 =
maximumPoolSize - corePoolSize
- 救急线程可以执行突发任务,比如任务队列选择有界队列,任务的数量超过了队列大小,就会创建
maximumPoolSize - corePoolSize
数目的救急线程来救急
- 救急线程数等于 =
- 最大线程数目
keepAliveTime
- 生存时间 - 针对救急线程
unit
- 时间单位 - 针对救急线程
workQueue
threadFactory
- 线程工厂 - 可以为线程创建时起个好名字
handler
关于上述的用法可以参考 自定义阻塞队列
如果线程达到 maximumPoolSize
任有新任务,则会执行拒绝策略,拒绝策略由 JDK
提供了 4
种实现
AbortPolicy
- 让调用者抛出
RejectedExecutionException
异常,这是默认策略
- 让调用者抛出
CallerRunsPolicy
- 让调用者运行任务
DiscardPolicy
- 放弃本次任务
DiscardOldestPolicy
- 放弃队列中最早的任务,本任务取而代之
除此之外,其他框架的实现如下
Dubbo
- 在抛出
RejectedExecutionException
异常前会记录日志,并dump
线程栈信息,方便定位问题
- 在抛出
Netty
- 创建一个新的线程执行任务
ActiveMQ
- 带超时等待(60s)尝试放入队列
PinPoint
- 使用了拒绝策略链,会逐一尝试策略链中每种拒绝策略
当高峰过去后,超过 corePoolSize
的救急线程,如果有一段时间没有任务做,需要结束节省资源,这个时间由 keepAliveTime
和 unit
控制。
根据这个构造方法,JDK Executors
类中提供了众多工厂方法来创建各种用途的线程池。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK