并发基础中的Future异步回调模式
1.1 问题?
在多模块架构下,一个模块可能需要调用其他的多个模块,那么如何能做到异步的调用这些模块而且同步的处理这些接口的返回结果勒?
1.2 从一个具体的实例聊起
我们要烧一壶茶,需要怎么做?
- 需要清洗茶具
- 烧水
- 泡茶
前两件事是可以同时进行的,等这两件事情做好了以后,才能干第三件事情。
1.3 具体的实现方式
1.3.1 join异步阻塞
所谓的异步阻塞就是阻塞当前线程然后,直到准备合并的线程执行完毕。
流程比较好理解,开启主线程,然后再开启清洗茶具和烧水的线程,接着使用join来阻塞主线程,等这两件事都完成后主线程才开始继续。
1.3.2 FutureTask
我们知道Runnable接口,我们可以实现这个接口,然后放到一个Thread中去。但是这个做法有个问题,就是它是无法给返回值的,要解决这个问题,我们可以用到Callable接口,但是为了能把这个接口放到Thread中去,就需要FutureTask这个类来作适配了,FutureTask间接继承了Runnable接口并持有Callable的属性,这样就很聪明的适配了。
在我们理解了FutureTask后,代码也是很简单的,但是它的问题依然存在,那就是,它依然是阻塞的,在主线程上调用了FutureTask从Future哪里继承来的get方法后,就会阻塞。所以从这点看来,他与前面讲的join方法,没有什么本质区别。
1.3.3 Netty的异步回调
我们在netty中可以看到许多操作,如对通道的连接,写,读,都会返回一个ChannelFutre对象,我们可以对这个对象配置一个监听器,他是GenericFutureListener的继承者ChannelFutreListener的实现类。需要实现一个operationComplete的回调方法,说明操作完成后需要干什么事。 这才是一个正真的异步非阻塞的实现方式。