Java线程池实现原理
ThreadPoolExecutor是jdk提供的线程池实现,ThreadPoolExector实现了Execturo接口,可以自动帮助用户创建,销毁和保护线程,先来看一下最基本的使用方式
创建一个线程池
final Executor executor = new ThreadPoolExecutor(10,10,-1, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(100));
ThreadPoolExectuor的构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
这里先简单描述一下参数的含义
corepooleSize: 表示核心线程数
maximumPoolSize : 表示最大线程数,当线程数等于corePoolSize的时候,如果继续提交任务就会创建新的线程,直到线程数等于maximumPoolSize
keepAliveTime:线程空闲时间,超过该事件线程就会被销毁掉。
workQueue : 任务队列,当无法继续创建线程的时候就把任务塞到任务队列中,可以看做是一个缓冲区,线程池中的线程会从该队列中pool task来执行
线程池状态
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
线程池中使用一个原子对象来存储当前线程池的状态,当前线程池的状态包括当前线程池中线程数量已经当前线程池的运行状态。其中高三位用来描述当前线程的运行状态
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
剩下的数位用来描述当前线程池中线程的数量。
任务提交过程
在使用线程池的时候,用户不需要关心线程的创建和销毁,用户只需要每次向线程池提交任务,下面我们可以看一下用户提交任务的时候线程池都发生了什么。
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get(); //获取线程池状态
if (workerCountOf(c) < corePoolSize) { //如果当前线程数小于corePoolSize
if (addWorker(command, true)) //新增一个线程
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) { //如果当前线程已经等于corePoolSize了就尝试把任务添加到任务队列中
int recheck = ctl.get(); //重新检查状态
if (! isRunning(recheck) && remove(command))
reject(command);//如果线程池没有运行,执行rejectHandler
else if (workerCountOf(recheck) == 0) //线程数如果为0,那么新增一个线程
addWorker(null, false);
}
else if (!addWorker(command, false)) //新增一个任务
reject(command);
addworker方法
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && ! (rs == SHUTDOWN &&
firstTask == null && ! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize)) //线程数已经超过了限定数量,直接返回错误
return false;
if (compareAndIncrementWorkerCount(c))//原子的增加线程数,如果成功原子更新成功,就跳出,否则继续循环
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask); //新建一个worker
final Thread t = w.thread; //获取新worker的线程
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) { //查看当前线程池的状态,如果当前线程池已经关闭了,那么就把当前线程关闭掉
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w); //把worker加到集合中
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
Worker定义
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
final Thread thread;//绑定一个线程
Runnable firstTask; //初始化时候执行任务
/** Per-thread task counter */
volatile long completedTasks;
Worker(Runnable firstTask) {
setState(-1); //禁止中断
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this); //创建一个线程
}
//启动一个事件循环
public void run() {
runWorker(this);
}
// The value 0 represents the unlocked state.
// The value 1 represents the locked state.
protected boolean isHeldExclusively() {
return getState() != 0;
}
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
}
Worker简单实现了AQS框架,在修改worker属性的时候可以对worker加锁处理。
runWorker方法
runWorker实现了一个事件循环,不断的从workQueue中拉取task,如果拉取的task为null,那么线程就退出
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) { //查看task,getTask()是从workQueue中拉取任务
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
//任务运行前处理,默认为noop
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run(); //执行任务
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);//任务执行后处理,默认noop
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
//当用户的任务抛异常的时候在这里进行处理,此时当前线程会销毁,在processWorkerExit中会新增一个线程,保证线程池数量保持稳定
processWorkerExit(w, completedAbruptly);
}
}