[Q&A] 当向线程池提交一个任务之后,线程池是如何处理这个任务的呢?
# 首先检测线程池运行状态,如果不是RUNNING则直接拒绝
① workerCount < corePoolSize
# 创建新线程来执行任务,即使线程池中有空闲线程,也会创建一个新的线程来执行新添加的任务(注意,执行这一步骤需要获取全局锁)
② workerCount >= corePoolSize && 阻塞队列未满
# 将任务加入BlockingQueue
③ workerCount >= corePoolSize && 阻塞队列已满 && workerCount < maximumPoolSize
#创建新的线程来处理任务(注意,执行这一步骤需要获取全局锁)
④ workerCount >= corePoolSize && 阻塞队列已满 && workerCount >= maximumPoolSize
# 启用拒绝策略
[Q&A] ThreadPoolExecutor
执行示意图 → (对应处理流程的①②③④)
工作线程
线程池创建线程时,会将线程封装成工作线程Worker
,Worker在执行完任务后,还会循环获取工作队列里的任务来执行。我们可以从Worker类的run()方法里看到这点。
public void run() {
try {
Runnable task = firstTask;
firstTask = null;
while (task != null || (task = getTask()) != null) {
runTask(task);
task = null;
}
} finally {
workerDone(this);
}
}
线程池中的线程执行任务分两种情况,如下。
1)在 execute()
方法中创建一个线程时,会让这个线程执行当前任务。
2)这个线程执行完上图中 1
的任务后,会反复从 BlockingQueue
获取任务来执行。
-----------------------------------------------------------------------------读书笔记摘自 书名:Java并发编程的艺术 作者:方腾飞;魏鹏;程晓明