没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
Java异步编程框架之Promise介绍
sorphi 的記事本 异步编程
Java异步编程框架之Promise介绍
异步概念
和同步的区别
caller获取执行结果
callee执行机制
异步模式的场景
异步API的几种风格
Callback
Future/Promise
ReactiveX
Promise的用法
符合Promise风格的方法签名
串行调用
并行调用
调用编排
异常处理
Promise异步编程的注意点
异步概念
同步(Synchronous)/异步(Asynchronous),通常是指函数调用中的消息通信的两种不同模式。
和同步的区别
函数调用发生时,消息(参数)从caller传递到callee,控制权从caller转移到callee。调用返回时,控制权从callee转移到caller。两者的
区别在于,callee是否需要等待执行完成才将控制权转移给caller。
同步 异步
1.callee执行完成才返回
2.返回值即结果
1.callee不需要执行完成就可返回
2.caller要获取结果,需要通过轮询、回调等机制
在RPC这种更复杂的场景下,本质上并没有不同。
同步 异步
caller获取执行结果
caller调用callee时,如果需要获取执行结果(消息双向传递),或者获知执行是否完成(消息单向传递无返回值),在异步模式
下,主要依靠下面两种机制。
轮询(Polling)
比如Java的 Future 就提供了 isDone() 这种询问机制。
或阻塞版本
轮询的控制逻辑在caller端。
回调(Callback)
caller设置一个回调函数,供callee执行完成后调用这个函数。回调的控制是反转的,通常由callee端控制。
callee执行机制
//Caller.java
void call() {
Future<Void> f = callee.asyncCall(param);
// do some other things
while(true) {
if (f.isDone()) break;
//do some other things or sleep or timeout
}
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
//Caller.java
void call() {
Future<Void> f = callee.asyncCall(param);
// do some other things
f.get(timeout, TimeUnit.SECONDS);
}
1.
2.
3.
4.
5.
6.
//Caller.java
void callerDemo() {
callee.asyncCall(param, new AsyncHandler<Response<Message>>() {
@Override public void handleResponse(Response<Message> response) {
msg = response.get();
// process the msg...
}
});
// do some other things
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
callee在执行尚未完成即将控制权转移给caller,那么具体的执行通常采用下面两种机制来完成。
线程池
将执行提交给额外的线程去执行。典型的如 ThreadPoolExecutor.submit(...) 。
基于状态机的EventLoop1
记录状态,延缓(Deferred),在下个事件循环时再执行。
异步模式的场景
阻塞
阻塞(Blocking)/非阻塞(Non-Blocking)是用来描述,在等待调用结果时caller线程的状态。阻塞,通常意味着caller线程不再使用CPU
时间,处于可被OS调度的状态(注意与Java线程状态2的区别)。
磁盘IO和网络IO是常见的会引起线程阻塞的场景3。受制于底层OS的同步阻塞式IO系统函数,调用Java OIO(Old blocking IO) API
无疑是会阻塞的。对于DiskIO,Java NIO2提供了异步API。对于SocketIO,Java NIO2以及NIO框架Netty,都提供了异步API。
Linux提供了异步IO系统函数,只能用于DiskIO,还有一些限制4,Java NIO2 AsynchronousFileChannel 内部仍然
使用线程池+阻塞式API的实现。
Linux为SocketIO准备就绪阶段提供了非阻塞式API(select/poll/epoll),但是IO执行阶段仍然是同步阻塞的,因此主流
的Java NIO框架的Reactor模式内部实现使用了线程池。
并行
比如需要调用多个没有依赖关系的服务,或者访问分散在多个存储分片中的数据,如果服务接口或数据访问接口实现了异步API,那
么就很方便实现并行调用,减少总体调用耗时。
速度不匹配
使用中间队列解偶caller和callee,削峰填谷。
批量
callee有机会能够合并(Merge)或批量(Batching)处理队列中的消息,减少系统调用次数。通过平衡批量消息数量和等待时间,通常是
在不明显降低延时的前提下提高吞吐量的很重要的手段。
异步API的几种风格
Callback
这个比较传统,比如zookeeper客户端提供的基于回调的异步API:
try {
zookeeper.create(path, data, acl, createMode, new StringCallback() {
public void processResult(int rc, String path, Object ctx, String name) {
if (rc != KeeperException.Code.OK.intValue()) {
// error handle
} else {
// success process
// 如果需要在成功后再发起基于回调的异步调用,会形成callback hell
}
}
}, ctx);
} catch( Throwable e) {
// error handle
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
剩余14页未读,继续阅读
资源评论
iamstrong01
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 实现了7种排序算法.三种复杂度排序.三种nlogn复杂度排序(堆排序,归并排序,快速排序)一种线性复杂度的排序.zip
- 冒泡排序 直接选择排序 直接插入排序 随机快速排序 归并排序 堆排序.zip
- 课设-内部排序算法比较 包括冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、归并排序和堆排序.zip
- Python排序算法.zip
- C语言实现直接插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序、归并排序、计数排序,并带图详解.zip
- 常用工具集参考用于图像等数据处理
- 音乐展示网页、基于Stenography的图像数字水印添加与提取,以及基于颜色矩和Tamura算法的图像相似度评估算法py源码
- 基于EmguCV(OpenCV .net封装),图像数字水印加解密算法的实现,其中包含最低有效位算法,离散傅里叶变换算法+文档书
- 基于matlab+DWT的图像水印项目,数字水印+源代码+文档说明+图片+报告pdf
- (优秀毕业设计)基于python实现的数字图像可视化水印系统的设计与实现,多种数字算法实现+源代码+文档说明+理论演示pdf
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功