线程池的基本结构
线程池主要线程和一个阻塞队列组成。
线程池的执行流程
大体流程当一个任务提交到线程池时
第一步 会先判断线程池里的核心线程是否都在执行任务;如果有可用线程并且当前线程池中的核心线程数还小于 corePoolSize则创建线程使用,否则就进入下一个流程;
第二步 线程池判断工作队列是否已满,如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下个流程;
第三步 判断线程池里的线程是否都处于工作状态,如果没有,查看一下当前线程数是否到达maximumPoolSize,如果还未到达,就继续创建线程。如果已经到达了,就交给RejectedExecutionHandler来决定怎么处理这个任务。
execute()方法
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
//如果线程数大于等于基本线程数或者线程创建失败,将任务加入队列
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
//线程池处于运行状态并且加入队列成功
if (runState == RUNNING && workQueue.offer(command)) {
if (runState != RUNNING || poolSize == 0)
ensureQueuedTaskHandled(command);
}
//线程池不处于运行状态或者加入队列失败,则创建线程(创建的是非核心线程)
else if (!addIfUnderMaximumPoolSize(command))
//创建线程失败,则采取阻塞处理的方式
reject(command); // is shutdown or saturated
}
}
addIfUnderCorePoolSize()
private boolean addIfUnderCorePoolSize(Runnable firstTask) {
Thread t = null;
final ReentrantLock mainLock = this.mainLock;
//阻塞锁
mainLock.lock();
try {
if (poolSize < corePoolSize && runState == RUNNING)
t = addThread(firstTask);
} finally {
mainLock.unlock();
}
if (t == null)
return false;
//启动线程
t.start();
return true;
}
addThread()方法
private Thread addThread(Runnable firstTask) {
Worker w = new Worker(firstTask);
Thread t = threadFactory.newThread(w);
if (t != null) {
w.thread = t;
workers.add(w);
int nt = ++poolSize;
if (nt > largestPoolSize)
largestPoolSize = nt;
}
return t;
}
网友评论