Future和FutureTask

1,Future

       java.util.concurrent.Future接口提供了线程不会因为等待返回结果而阻塞的能力。

       设想一个生活场景,用于需要申请车牌,它在提交了申请之后,与长达数小时的等待过程,在这个过程里,用户可以做自己想做的其他事情,而无需一直在窗口等待车牌制作完成。

       在这个过程中,用于可以放弃领取,也可以一直在窗口等待,也可以在窗口看看,能拿走则拿走,不行就在等一会去做别的事。

       Future模式就是提供了这样的能力,让线程可以灵活的确定自己在何时取得结果。

2,FutureTask

       java.util.concurrent.FutureTask是Future接口在concurrency包中的默认实现,它的主要用途之一是为了AbstractExecutorService提供任务支持,交由AbstractExecutorService执行的任务会被包装成一个FutureTask,以提供延时获取返回值的能力。

       FutureTask间接继承自Future接口和Runnable接口,所以,它同时具备执行任务和获取结果两种能力,FutureTask把实现委托给了其内部的AQS来实现。

       AQS是一个抽象队列同步器,内部维护了一个等待队列和等待状态。

3,Sync的四种状态

       Sync设计了四种状态,可见,Sync的实现也采用了状态机模式。

READY:任务准备完毕,可以运行

RUNNING:任务正在运行

RAN:任务运行完毕

CANCELLED:任务取消

4,Sync的运行

       innerRun的实现很简单:

1)       检查任务是否为READY状态,如果不是,那么认为已经被调用过了,直接返回。

2)       设置任务为RUNNING状态,表示当前Sync申领了该任务,如果该任务没有被其它线程修改,那么执行该任务。

3)       如果其它线程修改了该任务额状态,例如RAN或者CANCELLED,那么中断执行。

5,Sync的取消

       innerCancel方法的关键点有几处:

1)       只有READY或者RUN状态的任务才能取消。

2)       根据参数来决定是否要中断线程阻塞。

6,Sync获取数据

       innerGet方法用于异步获取数据,其逻辑实现如下:

1)       如果任务已经执行完成了,那么直接返回结果。

2)       如果任务尚未完成,那么等待任务完成后返回结果。

       通过对innerGet逻辑实现的分析,可以得出:

1)       线程访问innerGet时,如果任务不是RAN或者CANCELLED状态,那么线程会被阻塞。

2)       result来自于innerRun()里callable的返回值

7,Sync和AQS

     在运行/取消方法里,调用了tryReleaseShared,在取值方法里,调用了tryAcquiredShared,这两个try方法来自于AQS,分别用于在共享模式下线程释放锁和持有锁

1)       只有已经完成/取消的任务,才能即时获取结果。

2)       否则任务会等待执行完成或者被取消。

3)       取消节点是一定会生效的。

原文地址:https://www.cnblogs.com/guanghe/p/13502356.html