标签:原创
Java
并发
更多Java并发实战内容,请参考Java并发 - 并发编程实战
理解Future
关于Future模式的教程,网上很多,这里就不做详细介绍了。可参考的文章如:
Future关键点
这里重点对Future模式的几个关键点做下总结和扩展。
为什么需要Future
?
其实在多线程中,Future
的主要作用在于获取执行结果或执行状态。
当从主线程中启动一个子线程,那么子线程就像一匹脱缰的野马,很难知道什么时候执行完成,什么时候结束。
如果主线程依赖子线程的结果,由于不知道子线程的执行状态,就可能需要使用彻底理解Java的Future模式所讲的join方式去等待子线程返回结果。这种情况下,主线程会被阻塞,其实跟串行没有什么区别。因此,这种同步等待的方式是不可取的。
Future
模式就是为了实现主线程和子线程同时进行工作,在需要的时候,主线程才去等待子线程结果这种功能。
就像两个人一起算账,A(假设是主线程)算一部分,B(假设是子线程)算一部分,两个人同时计算自己的部分。当A算完以后,再通过Future.get()
方法来获取B计算的结果,最后进行累加。这时,如果B已经算完了,get()
方法直接返回结果。如果B还没算完,就等待B算完。
怎样使用Future
java concurrent包中的ThreadPoolExecutor
中有个sumbmit()
方法,返回的就是Future
对象:
public Future<?> submit(Runnable task);
public <T> Future<T> submit(Runnable task, T result);
public <T> Future<T> submit(Callable<T> task);
Future有什么缺点?
Future
有个大缺点就是没有办法异步化。也就是说,当子线程的处理结果需要进一步处理时,主线程需要调用get()
方法。但是get()
方法什么时候调用?这是个很难选择的时间点:可以任何时候调用!
如果立即调用,get()
方法会阻塞主线程,这又成串行执行了!
如果最后调用,子线程可能早就执行完了,还得保存结果,等待主线程处理!
计算机程序最浪费时间的操作就是"等待"
为了避免这种等待,最好使用回调的方式。举个例子:
主线程发起一个子线程去做一个事情后,继续执行。在主线程不依赖子线程结果的情况下,子线程处理完成后,将处理结果教给另一个线程去做记录。
这样,所有的线程都不会等待,还完成了各自的工作。
鉴于JDK Future
的缺点,并且解决速度很慢,Guava封装了增强版的Future
,供开发者使用
Guava Future
guava对Future
的增强可参考文章:
总结起来如下:
- JDK的
Future
,guava对应的增强版本是ListenableFuture
-
ListenableFuture
增加了void addListener(Runnable listener, Executor executor);
方法,可以让子线程在结束的时候,主动调用listener
对象,达到异步处理多结果 - JDK的
FutureTask
,guava对应的增强版本是ListenableFutureTask
- JDK的线程池返回的结果只有
Future
。所以为了支持返回ListenableFuture
,guava又封装了一系列的线程池,如:-
ListeningExecutorService
对应JDK的ExecutorService
-
MoreExecutors
对应JDK的Executors
-
- 还提供了能在调用线程中执行回调的
ExecutorService
,即DirectExecutor
guava增强的使用方法与JDK原生的大同小异
怎么使用guava Future?
从上得知,要使用guava的增强,需要使用guava线程池。guava在MoreExecutors
中提供了诸多方法,将JDK原生线程池,封装成适合guava体系的线程池,如:
public static ListeningExecutorService listeningDecorator(ExecutorService delegate);
public static ListeningScheduledExecutorService listeningDecorator(
ScheduledExecutorService delegate);
JDK8 CompletableFuture
除了guava扩展了Future
,Netty等高性能框架也扩展了Future
,可见JDK原生的Future
是多么不好用,牛B的程序员已经忍无可忍了。
JDK做为正统的Java类库,是不是该做点什么。
终于在JDK8的时候,千呼万唤,出现了CompletableFuture
:
关于CompletableFuture
的文章可参考:
网友评论