@FunctionalInterface publicinterfaceCallable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call()throws Exception; }
publicvoidrun(){ //首先判断任务的状态是不是新建 if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { //这里的callable是上面初始化的赋值过的,这里又赋值给v Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { //去执行具体的任务,并将结果放在临时result里面 result = c.call(); ran = true; } catch (Throwable ex) { //如果抛异常了,这里会将异常封装 具体看后面 result = null; ran = false; setException(ex); } //如果正常执行完任务,设置结果 具体看后面 if (ran) set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }
1 2 3 4 5 6 7 8 9 10 11
//任务正常执行情况 protectedvoidset(V v){ //跟新任务状态为完成 if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { //将结果赋值给成员变量outcome outcome = v; //更新状态为正常 UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state finishCompletion(); } }
1 2 3 4 5 6 7 8 9 10 11
//任务异常 protectedvoidsetException(Throwable t){ //更新任务状态为完成 if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { //将异常对象赋值给成员变量outcome outcome = t; //更新任务状态为异常 UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state finishCompletion(); } }
public V get()throws InterruptedException, ExecutionException { int s = state; //如果任务没有完成,则一直阻塞等待,直到任务完成 if (s <= COMPLETING) s = awaitDone(false, 0L); //返回结果 return report(s); }
1 2 3 4 5 6 7 8 9 10 11 12
private V report(int s)throws ExecutionException { //将结果赋值给x 这里可能是正常返回值,也可能是异常信息 Object x = outcome; //这里状态如果是正常的话直接将结果返回 if (s == NORMAL) return (V)x; //如果取消了任务就抛出取消异常 if (s >= CANCELLED) thrownew CancellationException(); //这里就是执行任务的时候有异常,线程池将异常封装成ExecutionException抛出。 thrownew ExecutionException((Throwable)x); }