Thread 创建线程实现 Runnable 接口 run 方法返回值为 void ,无法获取到线程的执行状态,执行结果。
public interface Runnable {
public abstract void run();
}
线程池设计时考虑到可能需要获取任务的返回值,新增了一个 Callable 接口比 Runnable 多了返回值 V
public interface Callable<V> {
V call() throws Exception;
}
由于任务是异步执行的,为了获取任务的执行结果,控制任务的执行 ,新增了一个接口 Future 用于获取任务的执行结果
public interface Future<V> {
// 取消任务执行 ,mayInterruptIfRunning 为 true ,调用执行任务线程的 interrupt()方法
boolean cancel(boolean mayInterruptIfRunning);
// 任务是否被取消
boolean isCancelled();
// 是否执行完成
boolean isDone();
// 获取执行结果,如果任务没有执行完成,会一直等待子任务完成
V get() throws InterruptedException, ExecutionException;
// 获取执行结果,如果任务没有执行完成,会等待 timeout 时间,如果在 timeout 时间内没有完成会抛出 TimeoutException 异常
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
Future 提供了 阻塞 或者 轮询 的方式得到任务的结果。
- Future.get() 就是阻塞调用,在线程获取结果之前 get方法会一直阻塞。
- Future提供了一个isDone方法,可以在程序中 轮询这个方法查询 执行结果。
以下是当一个Callable任务提交到线程池时,Future 是如何获取到 任务的执行结果的
// 当向线程池提交 Callable 时,会包装成为 RunnableFuture ,并且提交到线程池中执行 ,并返回
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
// RunnableFuture 继承了 Runnable 和 Future 接口
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
// newTaskFor 返回的是 FutureTask
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
public class FutureTask<V> implements RunnableFuture<V> {
private volatile int state;
private static final int NEW = 0;
private static final int COMPLETING = 1;
private static final int NORMAL = 2;
private static final int EXCEPTIONAL = 3;
private static final int CANCELLED = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED = 6;
private Callable<V> callable;
private Object outcome; // non-volatile, protected by state reads/writes
private volatile Thread runner;
private volatile WaitNode waiters;
// FutureTask 构造函数 ,FutureTask 有一个成员变量 state 记录了 任务的执行状态
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // 初始化时 当前状态为 NEW
}
}
FutureTask 状态有 7 中 ,流转情况有以下 4 种
---
title: FutureTask 正常执行完成
---
sequenceDiagram
NEW->>COMPLETING:
COMPLETING ->> NORMAL:
---
title: FutureTask 发生异常时
---
sequenceDiagram
NEW->>COMPLETING:
COMPLETING ->> EXCEPTIONAL:
---
title: FutureTask 执行时被取消
---
sequenceDiagram
NEW->>CANCELLED:
---
title: FutureTask 执行时调用中断方法
---
sequenceDiagram
NEW->>INTERRUPTING:
INTERRUPTING ->> INTERRUPTED:
需要注意,state 状态的改变是通过 CAS 操作的 ,上一个状态不匹配,状态是无法更新成功的
当 FutureTask 提交到线程池被执行时会调用 FutureTask 的 run 方法
public void run() {
// 初始化状态为 NEW ,并记录 runner 为当前线程
if (state != NEW ||
!RUNNER.compareAndSet(this, null, Thread.currentThread()))
return; // 如果有一个不成功说明状态异常(任务执行之前调用了 cancel()方法) ,直接返回
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call(); // 调用 call 方法拿到执行结果
ran = true; // 如果 call 方法不发生异常则 ran 为 true
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex); // 发生异常
}
if (ran) // 如果任务执行成功
set(result);
}
} finally {
// 线程执行完成 runner 设置为 null
runner = null;
int s = state;
if (s >= INTERRUPTING) // 状态如果为 INTERRUPTING ,需要等待状态 设置为 INTERRUPTED
handlePossibleCancellationInterrupt(s);
}
}
private void handlePossibleCancellationInterrupt(int s) {
if (s == INTERRUPTING)
while (state == INTERRUPTING) // 等待 INTERRUPTING 转化为 INTERRUPTED
Thread.yield(); // 放弃线程执行,INTERRUPTING 设置为 INTERRUPTED 速度非常快 ,
}
// 正常执行
protected void set(V v) {
// 状态设置为 COMPLETING
if (STATE.compareAndSet(this, NEW, COMPLETING)) {
outcome = v; // 存储任务执行结果
STATE.setRelease(this, NORMAL); // 最终状态
finishCompletion(); // 唤醒等待任务结果的线程
}
}
private void finishCompletion() {
// assert state > COMPLETING;
// WaitNode 是 一个链表结构,记录了等待当前线程执行任务完成而被阻塞的线程
// waiters 是头节点 ,如果头节点不为空,说明有其他线程调用了 get() ,等待任务完成
// 当任务完成时,需要唤醒其他线程
for (WaitNode q; (q = waiters) != null;) {
// 把头节点的值赋值给临时变量 q ,头节点设置为 null
if (WAITERS.weakCompareAndSet(this, q, null)) {
// for 循环遍历链表,唤醒每个等待任务执行结果的线程
for (;;) {
Thread t = q.thread;
if (t != null) {
q.thread = null;
LockSupport.unpark(t); // 唤醒线程
}
WaitNode next = q.next;
if (next == null) // next 为 null 说明到了结尾 退出循环
break;
q.next = null; // unlink to help gc
q = next;
}
break;
}
}
done(); // 通知任务执行完成
callable = null; // callable 设置为 null
}
static final class WaitNode {
volatile Thread thread; //记录线程
volatile WaitNode next; // 下一个节点
WaitNode() { thread = Thread.currentThread(); }
}
// 当任务执行发生了异常
protected void setException(Throwable t) {
if (STATE.compareAndSet(this, NEW, COMPLETING)) {
outcome = t; // 存储发生的异常对象
STATE.setRelease(this, EXCEPTIONAL); // 最终状态
finishCompletion(); // 唤醒等待任务结果的线程
}
}
// 取消任务 ,mayInterruptIfRunning 为 true 时 ,最终状态为 INTERRUPTED
// mayInterruptIfRunning 为 false 时 ,最终状态为 CANCELLED
// 执行过程中 如果 call 方法执行过程中被阻塞 ,比如调用了 wait() ,sleep()方法 。
// 另外一个线程调用了 cancel(true) , 虽然会抛出 InterruptedException 异常 ,
// 但是 state 已经设置为 INTERRUPTING ,setException() 方法中 CAS 会失败 ,最终状态为 CANCELLED
public boolean cancel(boolean mayInterruptIfRunning) {
// 当状态不为 NEW 时,无法取消成功
if (!(state == NEW && STATE.compareAndSet
(this, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt(); // 调用 interrupt 方法
} finally { // final state
STATE.setRelease(this, INTERRUPTED); // 设置最终状态
}
}
} finally {
finishCompletion(); // 唤醒等待任务结果的线程
}
return true; // 取消成功
}
// 无限时等待获取任务执行结果
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING) // 如果状态为 NEW ,COMPLETING ,说明还没到最终状态 ,等待任务完成
s = awaitDone(false, 0L); // 无限时等待任务完成
return report(s); // 返回最终结果
}
// 超时等待获取任务执行结果
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
// 如果状态为 NEW ,COMPLETING ,等待 timeout时间 ,如果 timeout 还未完成抛出TimeoutException 异常
if (s <= COMPLETING &&
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
throw new TimeoutException();
return report(s); // 返回最终结果
}
// 等待超时
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
long startTime = 0L; // Special value 0L means not yet parked
WaitNode q = null;
boolean queued = false;
for (;;) {
int s = state;
// 状态大于 COMPLETING 说明任务已完成 ,直接返回
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
}
// 状态等于 COMPLETING ,一个临界状态 ,很快就会有成功结果,或者抛 ExecutionException
else if (s == COMPLETING)
Thread.yield(); // 很快就能获取到结果交出执行权,下次调度时可能就有结果了
else if (Thread.interrupted()) { // 如果当前线程被中断,移除当前的等待节点 ,抛出InterruptedException 异常
removeWaiter(q);
throw new InterruptedException();
}
else if (q == null) {
if (timed && nanos <= 0L) // 设置超时参数非法,直接返回
return s;
q = new WaitNode(); // 新建节点
}
// q 赋值后 for 循环 走此分支
else if (!queued)
// 之前的头节点 waiters 赋值为 q.next ,并且 q 设置为头节点,设置成功后 queued 为 true
queued = WAITERS.weakCompareAndSet(this, q.next = waiters, q);
else if (timed) { // 如果设置超时
final long parkNanos;
if (startTime == 0L) { // 第一次
startTime = System.nanoTime(); // 赋值为当前时间
if (startTime == 0L)
startTime = 1L;
parkNanos = nanos;
} else { // 当超时时间到,但是任务还没完成时 for 循环 走此分支
long elapsed = System.nanoTime() - startTime;
if (elapsed >= nanos) { // 阻塞时间大于等于 nanos
removeWaiter(q); // 移除等待节点
return state; // 返回状态
}
parkNanos = nanos - elapsed;
}
// nanoTime may be slow; recheck before parking
if (state < COMPLETING)
// 阻塞线程 parkNanos 时间 ,当超时时间到,但是任务还没完成时,线程会被唤醒
LockSupport.parkNanos(this, parkNanos);
}
else
LockSupport.park(this); // 阻塞线程
}
}
private void removeWaiter(WaitNode node) {
if (node != null) {
node.thread = null; // 要移除的 node 节点的 thread 置为 null
retry:
for (;;) {
// waiters 为头节点 ,遍历链表 移除节点的 thread 为 null的节点 。
// 当 waiters 为 null 时 ,当前链表没有数据,不需要移除 ,直接跳出当前循环
for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
s = q.next;
if (q.thread != null)
pred = q; // 记录 thread 为 null 的上一个节点
else if (pred != null) {
pred.next = s; // pre.next 置为 s ,相当于移除 q 节点
// 检查临界情况 ,处理另外一个线程把 pred.thread 置为 null的情况 ,进行重新遍历
if (pred.thread == null)
continue retry;
}
// q.thread 为 null,说明该节点需要被移除 ,pred 也为 null,
// 说明 q 节点是头节点 并且是临界条件被另外一个线程被标记删除
// 需要重新设置头节点为 s ,设置失败进行重新遍历
else if (!WAITERS.compareAndSet(this, q, s))
continue retry;
}
break; // 没有进行 retry ,遍历完退出无限循环
}
}
}
// 返回结果
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL) // 如果正常执行,返回任务结果
return (V)x;
if (s >= CANCELLED) // 如果被取消,直接抛出 CancellationException 异常
throw new CancellationException();
// 任务执行过程中发生异常 ,抛出 CancellationException 异常
throw new ExecutionException((Throwable)x);
}
// 判断是否取消
public boolean isCancelled() {
return state >= CANCELLED;
}
// 是否完成
public boolean isDone() {
return state != NEW;
}
线程池也提供了提交 Runnable ,返回的是 Future<?> 类型 , 调用 get 返回得到的结果为 null
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null); // Runnable 返回结果为 null
execute(ftask);
return ftask;
}
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value); // 创建 FutureTask 对象
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result); // 通过 Runnable 生成 Callable 对象
this.state = NEW; // ensure visibility of callable
}
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
// Callable 适配器
private static final class RunnableAdapter<T> implements Callable<T> {
private final Runnable task;
private final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run(); // 运行 Runnable
return result; //返回结果
}
public String toString() {
return super.toString() + "[Wrapped task = " + task + "]";
}
}