Java 提供 Fork/Join 框架用于并行执行任务,核心的思想就是将一个大任务切分成多个小任务,然后汇总每个小任务的执行结果得到这个大任务的最终结果。
1. ForkJoinTask 的类定义
- 从定义可以看出,ForkJoinTask 实现 Future,Serializable。即 ForkJoinTask 是可异步、可序列化的抽象类任务。
public abstract class ForkJoinTask<V>
implements Future<V>, Serializable {}
- 横插一脚,先来看 Future 接口。
public interface Future<V> {
/* 试图取消执行任务, mayInterruptIfRunning: 是否应该中断 */
boolean cancel(boolean mayInterruptIfRunning);
/* 是否在完成任务之前被取消 */
boolean isCancelled();
/* 任务是否执行完成 */
boolean isDone();
/* 获取任务执行的返回结果 */
V get() throws InterruptedException, ExecutionException;
/* 最多等待给定的时间,获取任务执行的返回结果 */
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
1.1 ForkJoinTask 的属性
/* 万年不变版本号 */
private static final long serialVersionUID = -7721805057305804111L;
/* 任务状态,初始为 0 */
volatile int status; // accessed directly by pool and workers
/* 任务状态的掩码 */
static final int DONE_MASK = 0xf0000000; // mask out non-completion bits
/* 正常完成状态,负数,标识任务已经完成 */
static final int NORMAL = 0xf0000000;
/* 取消完成状态,负数,< NORMAL */
static final int CANCELLED = 0xc0000000;
/* 任务完成异常,负数,< CANCELLED */
static final int EXCEPTIONAL = 0x80000000;
/* 任务等待唤醒状态,正数 */
static final int SIGNAL = 0x00010000;
/* 低位掩码 */
static final int SMASK = 0x0000ffff; // short bits for tags
/* 异常表,底层是数组 */
private static final ExceptionNode[] exceptionTable;
/* 异常表锁,采用可重入锁 */
private static final ReentrantLock exceptionTableLock;
/* 异常引用队列 */
private static final ReferenceQueue<Object> exceptionTableRefQueue;
/* 异常表的固定容量 */
private static final int EXCEPTION_MAP_CAPACITY = 32;
// Unsafe mechanics
private static final sun.misc.Unsafe U;
private static final long STATUS;
/* 静态代码块,初始化静态属性 */
static {
exceptionTableLock = new ReentrantLock();
exceptionTableRefQueue = new ReferenceQueue<Object>();
exceptionTable = new ExceptionNode[EXCEPTION_MAP_CAPACITY];
try {
U = sun.misc.Unsafe.getUnsafe();
Class<?> k = ForkJoinTask.class;
STATUS = U.objectFieldOffset
(k.getDeclaredField("status"));
} catch (Exception e) {
throw new Error(e);
}
}
1.2 ForkJoinTask 的内部类
1.2.1 ExceptionNode
- 存储异常任务信息的节点
static final class ExceptionNode extends WeakReference<ForkJoinTask<?>> {
final Throwable ex; // 异常信息
ExceptionNode next; // next 指针
final long thrower; // 异常线程 id
final int hashCode; // 异常任务的 hashCode
ExceptionNode(ForkJoinTask<?> task, Throwable ex, ExceptionNode next) {
super(task, exceptionTableRefQueue);
this.ex = ex;
this.next = next;
this.thrower = Thread.currentThread().getId();
this.hashCode = System.identityHashCode(task);
}
}
1.2.2 AdaptedRunnable
- 如其名,适应 Runnable,即可以使用 Runnable 作为任务执行。
- 继承 ForkJoinTask,也就是说,还是一个分而治之的任务
static final class AdaptedRunnable<T> extends ForkJoinTask<T>
implements RunnableFuture<T> {
final Runnable runnable;
T result;
/* 指定 runnable 任务,结果为 result */
AdaptedRunnable(Runnable runnable, T result) {
if (runnable == null) throw new NullPointerException();
this.runnable = runnable;
this.result = result;
}
/* 获取结果值 */
public final T getRawResult() { return result; }
/* 设置结果值 */
public final void setRawResult(T v) { result = v; }
/* 任务执行的方法,返回 true */
public final boolean exec() { runnable.run(); return true; }
/* run() 方法,底层调用 invoke() */
public final void run() { invoke(); }
private static final long serialVersionUID = 5232453952276885070L;
}
1.2.3 AdaptedRunnableAction
- 没有返回值的 Runnable,其实就是一个返回值为 null 的 AdaptedRunnable
static final class AdaptedRunnableAction extends ForkJoinTask<Void>
implements RunnableFuture<Void> {
final Runnable runnable;
AdaptedRunnableAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
this.runnable = runnable;
}
public final Void getRawResult() { return null; }
public final void setRawResult(Void v) { }
public final boolean exec() { runnable.run(); return true; }
public final void run() { invoke(); }
private static final long serialVersionUID = 5232453952276885070L;
}
1.2.4 RunnableExecuteAction
- 为异常任务Runnable 做准备的类,在 ForkJoinTask 中没有使用
static final class RunnableExecuteAction extends ForkJoinTask<Void> {
final Runnable runnable;
RunnableExecuteAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
this.runnable = runnable;
}
public final Void getRawResult() { return null; }
public final void setRawResult(Void v) { }
public final boolean exec() { runnable.run(); return true; }
void internalPropagateException(Throwable ex) {
rethrow(ex);
}
private static final long serialVersionUID = 5232453952276885070L;
}
1.2.5 AdaptedCallable
- 如其名,适应 Callable,即可以使用 Callable 作为任务执行。
- 继承 ForkJoinTask,也就是说,还是一个分而治之的任务
static final class AdaptedCallable<T> extends ForkJoinTask<T>
implements RunnableFuture<T> {
final Callable<? extends T> callable;
T result;
AdaptedCallable(Callable<? extends T> callable) {
if (callable == null) throw new NullPointerException();
this.callable = callable;
}
public final T getRawResult() { return result; }
public final void setRawResult(T v) { result = v; }
/* 执行任务的方法,底层调用 callable.call() */
public final boolean exec() {
try {
result = callable.call();
return true;
} catch (Error err) {
throw err;
} catch (RuntimeException rex) {
throw rex;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public final void run() { invoke(); }
private static final long serialVersionUID = 2838392045355241008L;
}
2. ForkJoinTask 的 public 方法
2.1 fork()
- 将任务提交到任务队列中
public final ForkJoinTask<V> fork() {
Thread t;
/* 如果线程类型为ForkJoinWorkerThread,则将任务推入workQueue进行处理,
* 否则,交由ForkJoinPool的common线程池进行处 */
if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)
((ForkJoinWorkerThread)t).workQueue.push(this);
else
ForkJoinPool.common.externalPush(this);
return this;
}
2.2 join()
- 用于阻塞当前线程,等待任务执行完成
public final V join() {
int s;
/* 调用doJoin()进行任务的执行,若任务结果为非正常完成,则根据状态抛出不同的异常,
* 如若状态为CANCELLED,则抛出CancellationException(),异常;
* 若状态为EXCEPTIONAL,则抛出包装后的异常 */
if ((s = doJoin() & DONE_MASK) != NORMAL)
reportException(s);
return getRawResult();
}
2.3 invoke()
- 立即执行当前任务
public final V invoke() {
int s;
/* doInvoke() 执行任务并等待返回结果,若不为 NORMAL,抛出错误 */
if ((s = doInvoke() & DONE_MASK) != NORMAL)
reportException(s);
return getRawResult(); // 获取返回结果
}
2.4 invokeAll()
- 执行多个任务
/* 执行 t1, t2 任务 */
public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
int s1, s2;
t2.fork(); // 将 t2 任务添加至队列
if ((s1 = t1.doInvoke() & DONE_MASK) != NORMAL)
t1.reportException(s1);
if ((s2 = t2.doJoin() & DONE_MASK) != NORMAL)
t2.reportException(s2);
}
/* 从尾部开始遍历循环tasks,除task[0](即第一个任务)之外,全部执行 fork()
* 从 task[1] 开始遍历tasks,等待任务执行完成 doJoin() */
public static void invokeAll(ForkJoinTask<?>... tasks) {
Throwable ex = null;
int last = tasks.length - 1;
for (int i = last; i >= 0; --i) {
ForkJoinTask<?> t = tasks[i];
if (t == null) {
if (ex == null)
ex = new NullPointerException();
}
else if (i != 0)
t.fork();
else if (t.doInvoke() < NORMAL && ex == null)
ex = t.getException();
}
for (int i = 1; i <= last; ++i) {
ForkJoinTask<?> t = tasks[i];
if (t != null) {
if (ex != null)
t.cancel(false);
else if (t.doJoin() < NORMAL)
ex = t.getException();
}
}
if (ex != null)
rethrow(ex);
}
/* 执行集合的所有的任务 */
public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks) {
if(!(tasks instanceof RandomAccess) || !(tasks instanceof List<?>)) {
invokeAll(tasks.toArray(new ForkJoinTask<?>[tasks.size()]));
return tasks;
}
@SuppressWarnings("unchecked")
List<? extends ForkJoinTask<?>> ts =
(List<? extends ForkJoinTask<?>>) tasks;
Throwable ex = null;
int last = ts.size() - 1;
for (int i = last; i >= 0; --i) {
ForkJoinTask<?> t = ts.get(i);
if (t == null) {
if (ex == null)
ex = new NullPointerException();
}
else if (i != 0)
t.fork();
else if (t.doInvoke() < NORMAL && ex == null)
ex = t.getException();
}
for (int i = 1; i <= last; ++i) {
ForkJoinTask<?> t = ts.get(i);
if (t != null) {
if (ex != null)
t.cancel(false);
else if (t.doJoin() < NORMAL)
ex = t.getException();
}
}
if (ex != null)
rethrow(ex);
return tasks;
}
2.5 cancel(boolean mayInterruptIfRunning)
- 取消任务
public boolean cancel(boolean mayInterruptIfRunning) {
return (setCompletion(CANCELLED) & DONE_MASK) == CANCELLED;
}
2.6 isDone()
- 任务是否已经完成
public final boolean isDone() {
return status < 0;
}
2.7 isCancelled()
- 任务是否已经被取消
public final boolean isCancelled() {
return (status & DONE_MASK) == CANCELLED;
}
2.8 isCompletedAbnormally()
- 任务是否非正常执行完成
public final boolean isCompletedAbnormally() {
return status < NORMAL;
}
2.9 isCompletedNormally()
- 任务是否正常执行完成
public final boolean isCompletedNormally() {
return (status & DONE_MASK) == NORMAL;
}
2.10 getException()
- 获取对应的异常,正常完成为 null
public final Throwable getException() {
int s= status & DONE_MASK;
return ((s >= NORMAL) ? null :
(s == CANCELLED) ? new CancellationException() :
getThrowableException());
}
2.11 completeExceptionally(Throwable ex)
public void completeExceptionally(Throwable ex) {
setExceptionalCompletion((ex instanceof RuntimeException) ||
(ex instanceof Error) ? ex :
new RuntimeException(ex));
}
2.12 complete(V value)
- 任务完成,设置返回值
public void complete(V value) {
try {
setRawResult(value); // 设置返回值
} catch (Throwable rex) {
setExceptionalCompletion(rex); // 设置异常
return;
}
setCompletion(NORMAL); // 设置完成状态
}
2.13 quietlyComplete()
- 静悄悄的完成,设置完成状态为 NORMAL = 0xf0000000,没有返回值
public final void quietlyComplete() {
setCompletion(NORMAL);
}
2.14 get()
- 获取返回值,如果需要,进行等待
public final V get() throws InterruptedException, ExecutionException {
/* 等待返回状态 s */
int s= (Thread.currentThread() instanceof ForkJoinWorkerThread) ?
doJoin() : externalInterruptibleAwaitDone();
Throwable ex;
/* s 为异常完成状态,抛出对应的异常 */
if ((s &= DONE_MASK) == CANCELLED)
throw new CancellationException();
if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
throw new ExecutionException(ex);
return getRawResult(); // 返回结果
}
2.15 get(long timeout, TimeUnit unit)
public final V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
int s;
/* 等待时间 */
long nanos = unit.toNanos(timeout);
/* 判断是否中断 */
if (Thread.interrupted())
throw new InterruptedException();
/* status >= 0 即任务未执行完成 && 等待时间 > 0 */
if ((s = status) >= 0 && nanos > 0L) {
long d = System.nanoTime() + nanos;
long deadline = (d == 0L) ? 1L : d; // 不足 1L 设置为1,避免出现为 0 的情况
/* 若当前线程为 ForkJoinWorkerThread 的实例,进行 awaitJoin 等待 */
Thread t = Thread.currentThread();
if (t instanceof ForkJoinWorkerThread) {
ForkJoinWorkerThread wt = (ForkJoinWorkerThread)t;
s = wt.pool.awaitJoin(wt.workQueue, this, deadline);
}
/* 若当前线程为 CountedCompleter 的实例,先帮助其完成任务 */
else if ((s = ((this instanceof CountedCompleter) ?
ForkJoinPool.common.externalHelpComplete(
(CountedCompleter<?>)this, 0) :
ForkJoinPool.common.tryExternalUnpush(this) ?
doExec() : 0)) >= 0) {
long ns, ms; // 以毫微秒为单位进行判断,但以毫秒为单位
/* 循环 CAS 设置 status */
while ((s = status) >= 0 &&
(ns = deadline - System.nanoTime()) > 0L) {
/* 是否超过等待时间 && CAS设置有线程在等待 */
if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) > 0L &&
U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
synchronized (this) {
if (status >= 0)
wait(ms); // 任务未完成,等待唤醒
else
notifyAll(); // 任务已完成,唤醒所有争抢此锁的线程
}
}
}
}
}
if (s >= 0)
s = status;
/* 非正常完成 */
if ((s &= DONE_MASK) != NORMAL) {
Throwable ex;
if (s == CANCELLED)
throw new CancellationException();
if (s != EXCEPTIONAL)
throw new TimeoutException();
if ((ex = getThrowableException()) != null)
throw new ExecutionException(ex);
}
return getRawResult();
}
2.16 quietlyJoin()
- 静悄悄等待任务完成,没有返回值
public final void quietlyJoin() {
doJoin();
}
2.17 quietlyInvoke()
- 静悄悄的执行任务
public final void quietlyInvoke() {
doInvoke();
}
2.18 helpQuiesce()
- 帮助线程终止?
public static void helpQuiesce() {
Thread t;
if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) {
ForkJoinWorkerThread wt = (ForkJoinWorkerThread)t;
wt.pool.helpQuiescePool(wt.workQueue);
}
else
ForkJoinPool.quiesceCommonPool();
}
2.19 reinitialize()
- 将任务恢复至初始状态
public void reinitialize() {
if ((status & DONE_MASK) == EXCEPTIONAL)
clearExceptionalCompletion(); // 清除当前任务的错误状态
else
status = 0;
}
2.20 getPool()
- 获取 ForkJoinPool 池
public static ForkJoinPool getPool() {
Thread t = Thread.currentThread();
return (t instanceof ForkJoinWorkerThread) ?
((ForkJoinWorkerThread) t).pool : null;
}
2.21 inForkJoinPool()
- 是否为 ForkJoinWorkerThread 的实例
public static boolean inForkJoinPool() {
return Thread.currentThread() instanceof ForkJoinWorkerThread;
}
2.22 tryUnfork()
- 将任务从池中弹出
public boolean tryUnfork() {
Thread t;
return (((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
((ForkJoinWorkerThread)t).workQueue.tryUnpush(this) :
ForkJoinPool.common.tryExternalUnpush(this));
}
2.23 getQueuedTaskCount()
- 获取队列任务的个数
public static int getQueuedTaskCount() {
Thread t; ForkJoinPool.WorkQueue q;
if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)
q = ((ForkJoinWorkerThread)t).workQueue;
else
q = ForkJoinPool.commonSubmitterQueue();
return (q == null) ? 0 : q.queueSize();
}
2.24 getSurplusQueuedTaskCount()
- 获取队列中剩余任务的大致个数
public static int getSurplusQueuedTaskCount() {
return ForkJoinPool.getSurplusQueuedTaskCount();
}
2.25 getForkJoinTaskTag()
- 获取 ForkJoinTask 的状态
public final short getForkJoinTaskTag() {
return (short)status;
}
2.26 setForkJoinTaskTag(short tag)
- 设置 ForkJoinTask 的状态
public final short setForkJoinTaskTag(short tag) {
for (int s;;) {
if (U.compareAndSwapInt(this, STATUS, s = status,
(s & ~SMASK) | (tag & SMASK)))
return (short)s;
}
}
2.27 compareAndSetForkJoinTaskTag(short e, short tag)
- CAS 设置 ForkJoinTask 的状态
public final boolean compareAndSetForkJoinTaskTag(short e, short tag) {
for(int s;;) {
if ((short)(s = status) != e)
return false;
if (U.compareAndSwapInt(this, STATUS, s,
(s & ~SMASK) | (tag & SMASK)))
return true;
}
}
2.28 adapt(Runnable runnable)
- 指定任务runnable,没有返回值
public static ForkJoinTask<?> adapt(Runnable runnable) {
return new AdaptedRunnableAction(runnable);
}
2.29 adapt(Runnable runnable, T result)
- 指定任务runnable,具有返回值 result
public static <T> ForkJoinTask<T> adapt(Runnable runnable, T result) {
return new AdaptedRunnable<T>(runnable, result);
}
2.30 adapt(Callable<? extends T> callable)
- 指定任务callable,返回值就是 callable 的返回值
public static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable) {
return new AdaptedCallable<T>(callable);
}
2.31 getRawResult()
- 抽象方法,交给子类去实现
public abstract V getRawResult(); // 获取返回的结果
protected abstract void setRawResult(V value); // 设置返回的结果
protected abstract boolean exec(); // 任务执行函数
3. ForkJoinTask 的非 public 方法
3.1 doJoin()
/* 1、若任务状态为正常完成(status < 0),则返回任务的正常完成状态;
* 2、若执行任务的当前线程类型为ForkJoinWorkerThread,且将任务从线程的工作队列中移除
* && 调用doExec()执行任务,若任务执行状态为正常结束,则返回状态,否则awaitJoin()等待任务结束。
* 3、否则调用externalAwaitDone()等待任务执行完成。 */
private int doJoin() {
ints; Thread t; ForkJoinWorkerThread wt; ForkJoinPool.WorkQueue w;
return (s = status) < 0 ? s :
((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
(w = (wt = (ForkJoinWorkerThread)t).workQueue).
tryUnpush(this) && (s = doExec()) < 0 ? s :
wt.pool.awaitJoin(w, this, 0L) :
externalAwaitDone();
}
3.2 doExec()
final int doExec() {
int s; boolean completed;
/* status >= 0 即当前有任务未完成 */
if ((s = status) >= 0) {
try {
/* 这里会去执行实现类的 compute 方法,并且返回 false */
completed = exec();
} catch (Throwable rex) {
/* 发生异常,执行设置异常的方法 */
return setExceptionalCompletion(rex);
}
/* 若 completed 为true,设置当前完成状态为 NORMAL */
if (completed)
s = setCompletion(NORMAL);
}
return s;
}
3.3 setCompletion(int completion)
/* completion: 需要设置的状态值 */
private int setCompletion(int completion) {
for (int s;;) {
/* 如果已完成,直接返回 */
if ((s = status) < 0)
return s;
/* CAS 设置状态 status */
if (U.compareAndSwapInt(this, STATUS, s, s | completion)) {
/* 如果status中有SIGNAL标识,即有线程在等待当前任务执行完成 */
if ((s >>> 16) != 0)
/* 唤醒等待的线程 */
synchronized (this) { notifyAll(); }
return completion;
}
}
}
3.4 doInvoke()
- 执行任务
private int doInvoke() {
int s; Thread t; ForkJoinWorkerThread wt;
/* doExec() 执行任务并返回状态 s
* 若 s < 0 即任务已完成,返回任务完成的状态
* 若 s >= 0 判断当前线程是否为 ForkJoinWorkerThread
* 若为 ForkJoinWorkerThread,通过awaitJoin方法等待任务执行完成
* 若为 普通的Java线程,通过 externalAwaitDone 等待任务执行完成 */
return (s = doExec()) < 0 ? s :
((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
(wt = (ForkJoinWorkerThread)t).pool.
awaitJoin(wt.workQueue, this, 0L) :
externalAwaitDone();
}
3.5 externalInterruptibleAwaitDone()
/* 逻辑同externalAwaitDone,区别在于如果被中断抛出异常
* externalAwaitDone不会抛出异常,如果被中断了会将当前线程标记为已中断 */
private int externalInterruptibleAwaitDone() throws InterruptedException {
int s;
if (Thread.interrupted())
throw new InterruptedException();
if ((s = status) >= 0 &&
(s = ((this instanceof CountedCompleter) ?
ForkJoinPool.common.externalHelpComplete(
(CountedCompleter<?>)this, 0) :
ForkJoinPool.common.tryExternalUnpush(this) ? doExec() :
0)) >= 0) {
while ((s = status) >= 0) {
if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
synchronized (this) {
if (status >= 0)
wait(0L);
else
notifyAll();
}
}
}
}
return s;
}
3.6 internalWait(long timeout)
final void internalWait(long timeout) {
int s;
if ((s = status) >= 0 && // force completer to issue notify
U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
synchronized (this) {
if (status >= 0)
try { wait(timeout); } catch (InterruptedException ie) { }
else
notifyAll();
}
}
}
3.7 externalAwaitDone()
private int externalAwaitDone() {
int s = ((this instanceof CountedCompleter) ? // try helping
ForkJoinPool.common.externalHelpComplete(
(CountedCompleter<?>)this, 0) :
ForkJoinPool.common.tryExternalUnpush(this) ? doExec() : 0);
if (s >= 0 && (s = status) >= 0) {
boolean interrupted = false;
do {
if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
synchronized (this) {
if (status >= 0) {
try {
wait(0L);
} catch (InterruptedException ie) {
interrupted = true;
}
}
else
notifyAll();
}
}
} while ((s = status) >= 0);
if (interrupted)
Thread.currentThread().interrupt();
}
return s;
}
3.8 recordExceptionalCompletion(Throwable ex)
- 记录异常并设置状态
final int recordExceptionalCompletion(Throwable ex) {
int s;
/* status >= 0 即当前有任务未完成,否则直接返回当前状态 */
if ((s = status) >= 0) {
/* 获取当前对象的 hash 值 */
int h = System.identityHashCode(this);
/* 可重入锁 */
final ReentrantLock lock = exceptionTableLock;
lock.lock();
try {
/* 循环删除 exceptionTableRefQueue 的所有异常节点 */
expungeStaleExceptions();
ExceptionNode[] t = exceptionTable;
int i = h & (t.length - 1);
/* 遍历判断当前对象是否在 exceptionTable 中已添加 */
for (ExceptionNode e = t[i]; ; e = e.next) {
if (e == null) {
t[i] = new ExceptionNode(this, ex, t[i]);
break;
}
/* 对象已存在于 exceptionTable */
if (e.get() == this)
break;
}
} finally {
lock.unlock();
}
/* 设置完成状态为 EXCEPTIONAL = 0x80000000 */
s = setCompletion(EXCEPTIONAL);
}
return s;
}
3.9 setExceptionalCompletion(Throwable ex)
- 记录 并且 传播 异常
private int setExceptionalCompletion(Throwable ex) {
/* 记录异常并返回完成的状态 */
int s = recordExceptionalCompletion(ex);
/* 当前状态为 EXCEPTIONAL,执行钩子方法 internalPropagateException(),默认空方法,交给子类自己去实现 */
if ((s & DONE_MASK) == EXCEPTIONAL)
internalPropagateException(ex);
return s;
}
3.10 cancelIgnoringExceptions(ForkJoinTask<?> t)
static final void cancelIgnoringExceptions(ForkJoinTask<?> t) {
if(t != null && t.status >= 0) {
try {
t.cancel(false);
} catch (Throwable ignore) {
}
}
}
3.11 clearExceptionalCompletion()
private void clearExceptionalCompletion() {
int h = System.identityHashCode(this);
final ReentrantLock lock = exceptionTableLock;
lock.lock();
try {
ExceptionNode[] t = exceptionTable;
int i = h & (t.length - 1);
ExceptionNode e = t[i];
ExceptionNode pred = null;
while (e != null) {
ExceptionNode next = e.next;
if (e.get() == this) {
if (pred == null)
t[i] = next;
else
pred.next = next;
break;
}
pred = e;
e = next;
}
expungeStaleExceptions();
status = 0;
} finally {
lock.unlock();
}
}
3.12 getThrowableException()
private Throwable getThrowableException() {
if((status & DONE_MASK) != EXCEPTIONAL)
return null;
int h = System.identityHashCode(this);
ExceptionNode e;
final ReentrantLock lock = exceptionTableLock;
lock.lock();
try {
expungeStaleExceptions();
ExceptionNode[] t = exceptionTable;
e = t[h & (t.length - 1)];
while (e != null && e.get() != this)
e = e.next;
} finally {
lock.unlock();
}
Throwable ex;
if (e == null || (ex = e.ex) == null)
return null;
if (e.thrower != Thread.currentThread().getId()) {
Class<? extends Throwable> ec = ex.getClass();
try {
Constructor<?> noArgCtor = null;
Constructor<?>[] cs = ec.getConstructors();// public ctors only
for (int i = 0; i < cs.length; ++i) {
Constructor<?> c = cs[i];
Class<?>[] ps = c.getParameterTypes();
if (ps.length == 0)
noArgCtor = c;
else if (ps.length == 1 && ps[0] == Throwable.class) {
Throwable wx = (Throwable)c.newInstance(ex);
return (wx == null) ? ex : wx;
}
}
if (noArgCtor != null) {
Throwable wx = (Throwable)(noArgCtor.newInstance());
if (wx != null) {
wx.initCause(ex);
return wx;
}
}
} catch (Exception ignore) {
}
}
return ex;
}
3.13 expungeStaleExceptions()
- 循环删除队列 exceptionTableRefQueue 的所有异常节点
private static void expungeStaleExceptions() {
/* 循环弹出队列的所有元素 */
for (Object x; (x = exceptionTableRefQueue.poll()) != null;) {
/* x 为 ExceptionNode 的实例 */
if (x instanceof ExceptionNode) {
/* 计算 hash 值,获取 exceptionTable 对应的桶位下标 */
int hashCode = ((ExceptionNode)x).hashCode;
ExceptionNode[] t = exceptionTable;
int i = hashCode & (t.length - 1);
ExceptionNode e = t[i];
ExceptionNode pred = null;
/* 找到异常节点 x 并删除 */
while (e != null) {
ExceptionNode next = e.next;
if (e == x) {
if (pred == null)
t[i] = next;
else
pred.next = next;
break;
}
pred = e;
e = next;
}
}
}
}
3.14 helpExpungeStaleExceptions()
static final void helpExpungeStaleExceptions() {
final ReentrantLock lock = exceptionTableLock;
if (lock.tryLock()) {
try {
expungeStaleExceptions();
} finally {
lock.unlock();
}
}
}
3.15 rethrow(Throwable ex)
static void rethrow(Throwable ex) {
if (ex != null)
ForkJoinTask.<RuntimeException>uncheckedThrow(ex);
}
3.16 uncheckedThrow(Throwable t)
@SuppressWarnings("unchecked")
static <T extends Throwable> void uncheckedThrow(Throwable t) throws T {
throw (T)t; // rely on vacuous cast
}
3.17 reportException(int s)
private void reportException(int s) {
if (s == CANCELLED)
throw new CancellationException();
if (s == EXCEPTIONAL)
rethrow(getThrowableException());
}
3.18 internalPropagateException(Throwable ex)
/* 异常完成的钩子方法 */
void internalPropagateException(Throwable ex) {}