Worker
实现Runnable,继承AQS;
Worker是对任务的封装,执行完一个任务,可以继续执行等待队列中的其它任务;
通过继承AQS,实现了非重入的互斥锁,实现互斥锁主要目的是为了中断的时候判断线程是在空闲还是运行。
状态变量:ctl
状态设计与ReentrantReadWriteLock设计相同,读写锁是高16位表示读锁状态,低16位表示写锁状态
# AtomicInteger 原子型,操作具有原子性
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
/**
* 高3位表示:线程池状态、低29位表示:工作的线程数
* 线程池最大容量:1^29 -1
* 为什么要这么拆分:线程池的状态有5个,需要3位二进制
*/
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
/**
* 获取线程池状态,当前状态与最大容量(29个1)取反后 进行【与计算】,前29位不会参与计算
* 1111 1111 1111 1111 1111 1111 1111 1111
* & 1110 0000 0000 0000 0000 0000 0000 0000
* 1110 0000 0000 0000 0000 0000 0000 0000
*/
private static int runStateOf(int c) { return c & ~CAPACITY; }
/**
* 1.获取当前工作线程数,当前状态与最大容量(29个1)进行【与计算】,前3位不会参与计算
* 1111 1111 1111 1111 1111 1111 1111 1111
* & 0001 1111 1111 1111 1111 1111 1111 1111
* 0001 1111 1111 1111 1111 1111 1111 1111
* 2.当前线程工作数包含:核心线程与非核心线程
*/
private static int workerCountOf(int c) { return c & CAPACITY; }
/**
* 通过【或计算】将runstate、workerCount 合并成一个变量
* 1110 0000 0000 0000 0000 0000 0000 0000
* | 0001 1111 1111 1111 1111 1111 1111 1111
* 1111 1111 1111 1111 1111 1111 1111 1111
*/
private static int ctlOf(int rs, int wc) { return rs | wc; }
/**
* 当前工作线程数自增,在#addWorker时会被调用
*/
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
/**
* 当前工作线程数自减
*/
private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}
线程池状态
// 线程池能够接受任务,并且可以运行队列中的任务
private static final int RUNNING = -1 << COUNT_BITS;
// 不接受新的任务,但是等待队列里的任务还是会执行,#shutDown后的状态
private static final int SHUTDOWN = 0 << COUNT_BITS;
// 不接受新的任务,不会执行队列中的任务,并且尝试去中断正在运行的任务,#shutDownNow后的状态
private static final int STOP = 1 << COUNT_BITS;
// 所有任务都已经终止,workCount值为0,转到TIDYING状态的线程即将要执行terminated()钩子方法
private static final int TIDYING = 2 << COUNT_BITS;
// #terminated 执行结束
private static final int TERMINATED = 3 << COUNT_BITS;
五种状态的转变:
RUNNING -> SHUTDOWN:调用了#shutdown方法,或者线程池实现了finalize方法,在里面调用了#shutdown。
(RUNNING or SHUTDOWN) -> STOP:调用了#shutdownNow
SHUTDOWN -> TIDYING:当队列和线程池均为空的时候
STOP -> TIDYING:当线程池为空的时候
TIDYING -> TERMINATED:terminated()钩子方法调用完毕
#execute
/**
* 1. 如果当前工作线程数 < 核心线程数,标记为核心线程,创建Worker执行;
* 2. 如果当前工作线程数 >= 核心线程数,添加到等待队列;
* 3. 如果当前工作线程数 >= 核心线程数 且 等待队列也满了,标记为非核心线程,创建Worker执行
* 4. 如果第3步返回false(当前工作线程数 > 指定的最大线程数),则执行拒绝策略
*/
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
// 当前工作线程数 < 核心线程数,调用addWorker,标记为核心线程
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
// 当前工作线程数 >= 核心线程数,将任务添加到等待队列
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
// 再次检测线程池状态,如果不为Running,删除已添加的任务
if (! isRunning(recheck) && remove(command))
// 执行拒绝策略
reject(command);
// 线程池处于RUNNING状态 或 线程池处于非RUNNING状态但是任务remove失败
else if (workerCountOf(recheck) == 0)
// 这行代码是为了SHUTDOWN状态下没有活动线程了,但是队列里还有任务没执行这种特殊情况
// 添加一个null任务是因为SHUTDOWN状态下,线程池不再接受新任务,该方法会创建新的线程,从队列中获取任务并执行。
// 清理队列中剩余的任务
addWorker(null, false);
}
// 当前工作线程数 >= 核心线程数 且 等待队列已满,调用addWorker,标记为非核心线程
else if (!addWorker(command, false))
// 执行拒绝策略
reject(command);
}
#addWorker
/**
* 1. 当前线程工作数 +1
* 2. 创建Worker,将worker与当前线程绑定
* 3. 添加worker到workers,记录线程池达到的最大数量
* 4. 执行worker#run
*/
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
/*
* 这条语句等价:rs >= SHUTDOWN && (rs != SHUTDOWN || firstTask != null || workQueue.isEmpty())
* 满足下列条件则直接返回false,线程创建失败:
* rs > SHUTDOWN: STOP || TIDYING || TERMINATED 此时不再接受新的任务,且所有任务执行结束
* rs = SHUTDOWN: firtTask != null 此时不再接受任务,但是仍然会执行队列中的任务
* rs = SHUTDOWN: firtTask == null && workQueue.isEmpty() 见execute方法的addWorker(null, false)
* 最后一种情况: SHUTDONW状态下,如果workQueue不为空继续往下执行
* execute()只有workCount==0的时,addWorker(null, false),firstTask才会为null。
* 也就是说线程池SHUTDOWN了不再接受新任务,但是此时workQueue队列不为空,那么还得创建线程把任务给执行完才行。
*/
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN && firstTask == null && !workQueue.isEmpty())
)
return false;
/* 执行到此:
* 1)线程池状态为RUNNING
* 2)线程池状态为SHUTDOWN,但是任务队列还有任务未执行
*/
for (;;) {
int wc = workerCountOf(c);
// 如果当前线程工作数 >= 线程池最大容量,返回false,
// 或者 如果当前线程是核心线程,大于核心线程数返回false,如果是非核心线程,大于创建时指定的最大线程数返回false
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
// 当前线程工作数+1
if (compareAndIncrementWorkerCount(c))
break retry;
// CAS自增失败,重新获取状态,如果线程状态发生改变退出循环,否则继续自旋
c = ctl.get();
if (runStateOf(c) != rs)
continue retry;
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
// 创建worker,将worker与w.thread进行绑定
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
// 加锁
mainLock.lock();
try {
// 重新检测线程池状态
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
// 如果线程还在执行中,则抛出异常。简单理解线程状态不是 NEW
if (t.isAlive())
throw new IllegalThreadStateException();
// 添加到worker集合,worker集合可以理解为真正的线程池
workers.add(w);
int s = workers.size();
// 记录线程池达到的最大数量
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
// 解锁
mainLock.unlock();
}
if (workerAdded) {
// 执行Worker#run
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
// 添加失败,当前线程工作数 -1
addWorkerFailed(w);
}
return workerStarted;
}
#runWorker
/*
* 1. 先执行worker自带的task,执行完之后赋值为null,再从等待队列继续获取task,如果等待队列也没有task退出循环,结束线程
* 2. task执行前,会通过worker#lock进行加锁,配置worker#tryLock,防止线程被中止
*/
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
// firstTask,未经历线程复用时的任务
Runnable task = w.firstTask;
w.firstTask = null;
// 允许线程中断
w.unlock();
boolean completedAbruptly = true;
try {
// 如果task为null,则从等待队列继续获取task,实现线程复用
while (task != null || (task = getTask()) != null) {
// 加锁,进行中的线程不允许中断
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 {
// 执行之前调用,子类自己实现
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);
}
} finally {
// 将task设为null,准备下次循环从等待队列中继续获取task
task = null;
w.completedTasks++;
// 解锁
w.unlock();
}
}
completedAbruptly = false;
} finally {
// 如果当前工作线程数 < 核心线程数,通过addWorker(null, false)创建worker,保持指定数量的核心线程存活
processWorkerExit(w, completedAbruptly);
}
}
#getTask
/**
* 1. 根据当前线程数是否 大于 核心线程数判断,当前线程是阻塞获取还是等待获取
*/
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// 如果线程池状态 >= stop || 等待队列为空,当前工作线程数-1【待研究】
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// 当前工作线程数 > 核心线程数,timed为true
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
// 【待研究】
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
// 如果当前工作线程数 > 核心线程数,那么只阻塞指定的keepAliveTime就退出,否则一直阻塞
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
#submit
# 有返回值,返回值为FutureTask
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
<T> Future<T> submit(Callable<T> task);
参数为Runnable时执行流程:
AbstractExecutorService#submit
-> new FutureTask
-> new RunnableAdapter(RunnableAdapter 实现了Callable,实现了call)
-> ThreadPoolExecutor#execute,参数为FutureTask
-> new Worker -> Worker#run -> Worker#runWorker ->Worker.task(FutureTask)#run
-> FutureTask#run -> Callable(RunnableAdapter)#call
-> Runnable实现类#run,执行业务代码
参数为Callable时执行流程:
AbstractExecutorService#submit
-> new FutureTask
-> ThreadPoolExecutor#execute,参数为FutureTask
-> new Worker -> Worker#run -> Worker#runWorker ->Worker.task(FutureTask)#run
-> FutureTask#run
-> Callable实现类#call,执行业务代码
Runnable、Callable、Future、FutureTask
Runnable
- 线程启动参数
- #run,无返回值,异常不会抛出(外部catch不到)
Callable
- 间接作为线程启动参数,需要FutureTask配合
- #call,有返回结果(Future类型 -> FutureTask),异常会抛出(外部可以catch到)
Future
- 接口,代表异步计算结果
- #get、#isDone、#cancel 等方法
FutureTask
- 可以提供异步计算结果的任务。因为其实现RunnableFuture接口,而RunnableFuture接口继承了Runnable、Future接口
- FutureTask可以用来包装 Runnable、Callable的实现类
适配器模式
FutureTask是Runnable的实现类,是Callable向Runnable的适配器,是类适配器方式
RunnableAdapter,Runnable转Callable,对象适配器实现
/**
* RunnableAdapter对象持有Runnable的引用, 而RunnableAdapter又实现于Callable
*/
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
// 在Callable#call中,执行Runnable#run
public T call() {
task.run();
return result;
}
}
问题
创建的核心线程会不会销毁
不会销毁:
在#runWorker的while循环中,getTask返回null,就会退出while循环,不在继续进行线程复用。
而#getTask方法,只有线程池当前工作线程数>核心线程数,且未从等待队列获取到task时,才会返回null,否则是会一直阻塞在workQueue#take方法。
Worker#runWorker,先执行w.unlock,允许线程中断什么意思
初始化Worker的时候会设置state为-1,在执行#runWorker的w.unlock时候会将state设置为0,当获取到task后,设置state为1;
#interruptIfStarted 会被#shutdownNow 调用到,这里有个判断,只有state >= 0时,才中断。