FutureTask疑问
我们知道通过FutureTask的get方法可以拿到Callable的返回值,起初猜想get方法应该是不断循环,判断Callable是否达到运行完成状态(会有标记位),如果未完成则wait,这个判断过程是需要加锁完成的,但查看其源码发现并没有锁机制,而是简单了wait,这样的话,难道不会出现Callable执行完成在先(并唤醒队列中线程),get的wait在后的情况?暂时不明白是什么原理,先记录下来。
1 public V get() throws InterruptedException, ExecutionException { 2 int s = state; 3 if (s <= COMPLETING) 4 s = awaitDone(false, 0L); 5 return report(s); 6 }
1 private int awaitDone(boolean timed, long nanos) 2 throws InterruptedException { 3 final long deadline = timed ? System.nanoTime() + nanos : 0L; 4 WaitNode q = null; 5 boolean queued = false; 6 for (;;) { 7 if (Thread.interrupted()) { 8 removeWaiter(q); 9 throw new InterruptedException(); 10 } 11 12 int s = state; 13 if (s > COMPLETING) { 14 if (q != null) 15 q.thread = null; 16 return s; 17 } 18 else if (s == COMPLETING) // cannot time out yet 19 Thread.yield(); 20 else if (q == null) 21 q = new WaitNode(); 22 else if (!queued) 23 queued = UNSAFE.compareAndSwapObject(this, waitersOffset, 24 q.next = waiters, q); 25 else if (timed) { 26 nanos = deadline - System.nanoTime(); 27 if (nanos <= 0L) { 28 removeWaiter(q); 29 return state; 30 } 31 LockSupport.parkNanos(this, nanos); 32 } 33 else 34 LockSupport.park(this);//全程无锁,只是在入队时使用了CAS 35 } 36 }