FutureTask常常用于包装任务,提交给Executor执行,本博客介绍JDK1.7的实现,如果想看JDK1.8的实现请移步FutureTask源码详解(JDK1.8)
继承结构
实现
FutureTask对外方法
FutureTask对外方法都通过内部类Sync来实现
Sync内部类实现
总结
通过内部继承AQS的一个私有类Sync来实现操作代理的;Sync 实现了AQS的tryAcquireShared()和tryReleaseShared()方法
FutureTask代的get()方法代理到AQS的acquireSharedInterruptibly()方法上
这个方法内部回调重写的tryAcquireShared()方法来判断acquire操作是否可以成功。
- 成功的条件为:state为执行完成状态RAN或已取消CANCELLED,且runner不为null。
- 如果成功则从get()方法返回,失败则进入AQS等待队列中,直到其他线程release(run,cancel)。
- 当其他线程执行AQS的release方法唤醒当前线程后,当前线程再次执行tryAcquireShared()方法将返回1(大于0的数表示成功),当前线程离开等待队列并唤醒后继线程(级联唤醒的效果)。
- 最后返回计算的结果或者抛出异常。
FutureTask的run()和cancel()方法代理到AQS的release()方法上
release()会回调tryReleaseShared()方法,看一下run方法的执行过程:
- 执行任务(Callable.call());
- 以原子的方式更新同步状态,如果这个操作成功就设置代表计算结果的变量result的值为Callable.call()的返回值,然后调用AQS的releaseShared()方法释放同步状态
- 先回调tryReleaseShared()方法,设置运行任务的线程为null,然后返回true。
- 然后执行AQS.releaseShared()方法,唤醒线程等待队列中的第一个线程(第一个被唤醒后,后面依次被唤醒)
- 执行FutureTask.done()方法,这是一个空方法。可以用来在这个方法内查询状态是否完成。
网友评论