Futuretask is the line routines code that wraps the callable object, giving detailed information about its status and changes during Operation:
/*** The run state of this task, initially NEW. The Run state * transitions to a terminal state is only in methods set, * SetException, and Cancel. During completion, State could take in * transient values of completing (while outcome is being set) or * Interrupti NG (only if interrupting the runner to satisfy A * Cancel (true)). Transitions from these intermediate to final * states use cheaper Ordered/lazy writes because values is unique * and cannot be further modified. * * Possible State transitions: * New, completing, NORMAL * NEW---completing exceptional * CANCELLED , new, interrupting, new--Interrupted*/ Private volatile intState ; Private Static Final intNEW = 0; Private Static Final intCompleting = 1; Private Static Final intNORMAL = 2; Private Static Final intexceptional = 3; Private Static Final intCANCELLED = 4; Private Static Final intinterrupting = 5; Private Static Final intinterrupted = 6;
See How Futuretask implements the Futrue interface to see the implementation of its get ()
/** * @throwscancellationexception {@inheritDoc} */ PublicV get ()throwsinterruptedexception, executionexception {ints =State ; if(S <=completing) S= Awaitdone (false, 0L); returnReport (s); } /*** Awaits completion or aborts on interrupt or timeout. * * @paramtimed True if use timed waits *@paramNanos Time to wait, if timed *@returnState upon completion*/ Private intAwaitdone (BooleanTimedLongNanos)throwsinterruptedexception {Final LongDeadline = timed? System.nanotime () + nanos:0l; Waitnode Q=NULL; BooleanQueued =false; for (;;) { if(thread.interrupted ()) {removewaiter (q); Throw Newinterruptedexception (); } ints =State ; if(S >completing) { if(Q! =NULL) Q.thread=NULL; returns; } Else if(s = = completing)//cannot time out yetThread.yield (); Else if(q = =NULL) Q=NewWaitnode (); Else if(!queued) Queued= Unsafe.compareandswapobject ( This, Waitersoffset, Q.next=waiters, q); Else if(timed) {Nanos= Deadline-System.nanotime (); if(Nanos <= 0L) {removewaiter (q); returnState ; } Locksupport.parknanos ( This, Nanos); } ElseLocksupport.park ( This); } }
This awaitdone function, implemented in the callable Object Not complete When the front thread waits for the function. Member variable waiters is a wait in the futuretask#get () waitnode There are current thread
/***/ privatevolatile waitnode waiters;
Awaitdone first joins the current thread 等待队列 ,然后调用LockSupport#park 阻塞自己,等待被唤醒再根据state 状态返回,或者过nanos 时间后返回。 park waiters 是“忙碌等待”的一种优化,它不会浪费这么多的时间进行自旋。 当执行Callable 的异步线程完成task 后,会唤醒阻塞在awaitDone 上的当前线程,看具体的实现:
Public voidrun () {if(state! = NEW | | !unsafe.compareandswapobject ( This, Runneroffset,NULL, Thread.CurrentThread ())) return; Try{callable<V> C =callable; if(c! =NULL&& state = =NEW) {V result; Booleanran; Try{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 was settled to//prevent concurrent calls to run ()Runner =NULL; //State must is re-read after nulling runner to prevent//leaked interrupts ints =State ; if(S >=interrupting) Handlepossiblecancellationinterrupt (s); } }
ran==true , perform set () Sets the result and calls finishcompletion () to clear and notify the waiting thread on the waiters .
/*** Removes and signals all waiting threads, invokes do (), and * nulls out callable. */ Private voidfinishcompletion () {//assert state > completing; for(Waitnode q; (q = waiters)! =NULL;) { if(Unsafe.compareandswapobject ( This, Waitersoffset, Q,NULL)) { for (;;) {Thread T=Q.thread; if(t! =NULL) {Q.thread=NULL; Locksupport.unpark (t); } Waitnode Next=Q.next; if(Next = =NULL) Break; Q.next=NULL;//unlink to help GCQ =Next; } Break; }} done (); Callable=NULL;//To reduce footprint}
Futuretask is through locksupport to block the thread and wake the thread. For multithreaded access featuretask the waiters,state , all using Unsafe featuretask is a Very good unsafe and locksupport example 。
Futuretask Source Reading