FutureTask中的waiters为啥这么设计
题主读源码的话,应该看到waiters的定义: /** Treiber stack of waiting threads */ private volatile WaitNode waiters; /** * Simple linked list nodes to record waiting threads in a Treiber * stack. See other classes such as Phaser and SynchronousQueue * for more detailed explanation. */ static final class WaitNode { volatile Thread thread; volatile WaitNode next; WaitNode() { thread = Thread.currentThread(); } }显然,waiters保留了在FutureTask上的等待线程列表,设计链表的意义? 因为Future的get()/get(timeout)在task处于非完成状态时是需要阻塞等待的,如果多个线程进行get操作,显然需要一个链表/队列来维护这些等待线程,这就是waiters的意义所在。
然后就是如何维护waiters,从Java1.7开始Doug Lea对FutureTask进行了重写,重写的原因:/* * Revision notes: This differs from previous versions of this * class that relied on AbstractQueuedSynchronizer, mainly to * avoid surprising users about retaining interrupt status during * cancellation races. Sync control in the current design relies * on a "state" field updated via CAS to track completion, along * with a simple Treiber stack to hold waiting threads. * * Style note: As usual, we bypass overhead of using * AtomicXFieldUpdaters and instead directly use Unsafe intrinsics. */即为了在需要竞争时保留中断状态,他对之前基于AQS的方式进行了重构,如果题主对AQS比较熟悉,可以看下1.6的FutureTask的实现,其实非常简单。
http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/5f4bfda58ef8/src/share/classes/java/util/concurrent/FutureTask.java
而为了维护状态,新版本的FutureTask采用了Treiber Stack - Wikipedia 方式,即通过CAS来维护内部的竞争状态,当然也包括了waiters(队头)的状态。
以awaitDone的waiters入队操作为例: private int awaitDone(boolean timed, long nanos) throws InterruptedException { final long deadline = timed ? System.nanoTime() + nanos : 0L; WaitNode q = null; boolean queued = false; for (;;) { if (Thread.interrupted()) { removeWaiter(q); throw new InterruptedException(); } int s = state; if (s \u0026gt; COMPLETING) { if (q != null) q.thread = null; return s; } else if (s == COMPLETING) // cannot time out yet Thread.yield(); else if (q == null) q = new WaitNode(); else if (!queued) queued = UNSAFE.compareAndSwapObject(this, waitersOffset, q.next = waiters, q); else if (timed) { nanos = deadline - System.nanoTime(); if (nanos \u0026lt;= 0L) { removeWaiter(q); return state; } LockSupport.parkNanos(this, nanos); } else LockSupport.park(this); } }
推荐阅读
- 鄂温克冬季马赛-30℃极寒开赛:寒冬中的火热派对
- 大雪@大雪腌肉 适当进补 今日大雪
- |电商事业中的“闪光少年”
- hadoop中的mapreduce链接(mapreduce chaining)怎样避免中间文件的产生
- 经观汽车|日系车企中的“异类”?东风日产将导入e-POWER技术大干增程式混动 | 经观汽车
- 中年|这些东西,比你想象中的还要大得多!
- 请问杨毅微博中的这两人是谁
- 某些公司招聘要求中的精通mysql是啥程度
- 宝宝|婴幼儿游泳——宝宝人生中的第一健身运动
- 汽车|你眼中的未来出行世界——YiMagazine x 道达尔
