案例:为了提升泡茶效率。下面分别是用阻塞模式和异步回调模式来实现其中的异步泡茶流程。
为了异步执行整个泡茶流程,分别设计三条线程:主线程、清洗线程、烧水线程。
(1)主线程(MainThread)的工作是:启动清洗线程、启动烧水线程,等清洗、烧水完成后,泡茶喝。
(2)清洗线程(WashThread)的工作是:洗茶壶、洗茶杯。
(3)烧水线程(HotWarterThread)的工作是:洗好水壶,灌上凉水,放在火上,一直等水烧开。
1.join异步阻塞
主线程通过分别调用烧水线程和清洗线程的join方法,等待烧水线程和清洗线程执行完成,然后执行自己的泡茶操作。
join有一个问题:被合并的线程没有返回值。例如,在烧水的实例中,如果烧水线程的执行结束,main线程是无法知道结果的。同样, 清洗线程的执行结果,main线程也是无法知道的。形象地说,join线程合并就是一像一个闷葫芦,只能发起合并线程,不能取到执行结果。如果需要获得异步线程的执行结果, 怎么办呢?可以使用Java的FutureTask系列类。
2.FutureTask类实现异步泡茶喝案例
要让线程有返回值,需要线程实现的接口由Runnable改为Callable<T>,并且在call方法中返回了异步线程的执行结果,这样主线程就能收到烧水线程和清洗线程的返回值。
因为通过FutureTask类的get方法,获取异步结果时,主线程也会被阻塞的。这一点,FutureTas和join也是一样的,它们俩都是异步阻塞模式。异步阻塞的效率往往是比较低的被阻塞的主线程不能干任何事情,唯一能干的,就是在傻傻地等待。原生Java API,除了阻塞模式的获取结果外,并没有实现非阻塞的异步结果获取方法。如
果需要用到获取异步的结果,则需要引、一些额外的框架,这里首先介绍谷歌公司的Guava框架。
3.GUuava的异步回调
Guava异步回调的流程如下:
第1步:实现Java的Callable接口,创建异步执行逻辑。还有一种情况,如果不需要返回值异步执行逻辑也可以实现Java的Runnable接口。
第2步:创建Guava线程池。
第3步:将第1步创建的Callable/Runnable异步执行逻辑的实例,通过submit提交到Guava线程池,从而获取ListenableFuture异步任务实例。
第4步:创建 FutureCallback 回调实例,通过 Futures.addCallback 将回调实例绑定到ListenableFuture异步任务上。
完成以上四步,当Callable/Runnable异步执行逻辑完成后,就会回调异步回调实例FutureCallback的回调方法onSuccess/onFailure。
4.Netty的异步回调模式
标签:异步,烧水,执行,阻塞,并发,Future,线程,回调 From: https://www.cnblogs.com/Yi-ling/p/18216421