java 分而治之的框架 ForkJoinTask

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) {}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值