java的FutureTask类用法
1.FutrueTask概念
FutureTask一个可勾销的异步计算,FutureTask 实现了Future的根本办法,提空 start cancel 操作,能够查问计算是否曾经实现,并且能够获取计算的后果。后果只能够在计算实现之后获取,get办法会阻塞当计算没有实现的时候,一旦计算曾经实现,那么计算就不能再次启动或是勾销。
一个FutureTask 能够用来包装一个 Callable 或是一个runnable对象。因为FurtureTask实现了Runnable办法,所以一个 FutureTask能够提交(submit)给一个Excutor执行(excution).
2.FutureTask应用场景
FutureTask可用于异步获取执行后果或勾销执行工作的场景。通过传入Runnable或者Callable的工作给FutureTask,间接调用其run办法或者放入线程池执行,之后能够在内部通过FutureTask的get办法异步获取执行后果,因而,FutureTask非常适合用于耗时的计算,主线程能够在实现本人的工作后,再去获取后果。另外,FutureTask还能够确保即便调用了屡次run办法,它都只会执行一次Runnable或者Callable工作,或者通过cancel勾销FutureTask的执行等。
2.1 FutureTask执行多任务计算场景
利用FutureTask和ExecutorService,能够用多线程的形式提交计算工作,主线程继续执行其余工作,当主线程须要子线程的计算结果时,在异步获取子线程的执行后果。
View Code
2.2 FutureTask在高并发下确保工作只执行一次
在很多高并发的环境下,往往咱们只须要某些工作只执行一次。这种应用情景FutureTask的个性恰能胜任。举一个例子,假如有一个带key的连接池,当key存在时,即间接返回key对应的对象;当key不存在时,则创立连贯。对于这样的利用场景,通常采纳的办法为应用一个Map对象来存储key和连接池对应的对应关系,典型的代码如上面所示:
View Code
在下面的例子中,咱们通过加锁确保高并发环境下的线程平安,也确保了connection只创立一次,然而确就义了性能。改用ConcurrentHash的状况下,简直能够防止加锁的操作,性能大大提高,然而在高并发的状况下有可能呈现Connection被创立屡次的景象。这时最须要解决的问题就是当key不存在时,创立Connection的动作能放在connectionPool之后执行,这正是FutureTask发挥作用的机会
FutureTask可用于异步获取执行后果或勾销执行工作的场景。通过传入Runnable或者Callable的工作给FutureTask,间接调用其run办法或者放入线程池执行,之后能够在内部通过FutureTask的get办法异步获取执行后果,因而,FutureTask非常适合用于耗时的计算,主线程能够在实现本人的工作后,再去获取后果。另外,FutureTask还能够确保即便调用了屡次run办法,它都只会执行一次Runnable或者Callable工作,或者通过cancel勾销FutureTask的执行等。
实现剖析
在剖析实现前,咱们先想下如果让咱们实现一个相似FutureTask的性能,咱们会如何做?因为须要获取执行后果,须要一个Object对象来存执行后果。工作执行工夫不可控性,咱们须要一个变量示意执行状态。其余线程会调用get办法获取后果,在没达到超时的时候须要将线程阻塞或挂起。
因而须要一个队列相似的构造存储期待该后果的线程信息,这样在工作执行线程实现后就能够唤醒XM返佣https://www.kaifx.cn/broker/x…,失去后果。FutureTask的理论实现也是相似的逻辑,具体如下。
首先看下FutureTask的次要成员变量如下:
1
2
3
4
5
6
7
8
//futureTask执行状态
private volatile int state;
//具体的执行工作,会在run办法中抵用callable.call()
private Callable callable;
//执行后果
private Object outcome;
//获取后果的期待线程节点
private volatile WaitNode waiters;
对于执行状态,在源码中曾经有了十分清晰的解释,这里我只是贴出源码,不在进行阐明,具体如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
Possible state transitions:
NEW -> COMPLETING -> NORMAL
NEW -> COMPLETING -> EXCEPTIONAL
NEW -> CANCELLED
NEW -> INTERRUPTING -> INTERRUPTED