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     }

 

posted @ 2018-04-08 16:54  holoyong  阅读(163)  评论(0编辑  收藏  举报