网站首页 > 精选教程 正文
开始之前
异步与回调,一个有趣的话题。我们总是对异步编程抱有很大的兴趣,因为正确的运用异步,可以使你的程序变快。但我们又想在异步完成时获得通知,怎么办?在java的concurrent包中提供了Future接口,可以获取异步调用的返回结果,但这个获取是同步的,显然破坏了异步的调用形式。那么本文将会阐述如何使用 回调机制 让程序真正的异步
回调
回调是一种双向调用:在类A的a()方法中调用了类B的b()方法,b()方法执行完之后调用A的callback来告知b()方法已经执行完毕,那么如何才能调用到callback()呢,或者说如何做到通知A呢,很显然b()方法执行时要持有A的引用,所以B的b方法应该是:b(A ref)。
类似下面的伪代码:
class A{
void a(B ref){
ref.b();
};
void callback();
}
class B{
void b(A ref){
...
ref.callback();
}
main(){
new A().a(new B());
}
}
上面这种是同步回调,即回调放在同一个线程内,但我们更关注文章开篇提到的异步回调。
异步回调
两大要素:
- 回调接口(Callback)
- 回调监听(CallbackListener)
被调用方返回一个Callback给调用方,调用方在Callback上注册监听。被调用方在程序最后执行监听。这里有一个注意点:当调用方在放置监听的时候发现被调用方已经完成了自己代码,则调用方需要立即执行监听。
下面是作者简单实现的异步回调例子:
public interface Callback{
public void addListener(CallbackListener listener);//注册监听
public void notifyListener();//唤起监听
public void setComplete(boolean b);//标记被调用方已完成
}
public interface CallbackListener{
public void operationComplete(Callback callBack);
}
public class DefaultCallback implements Callback {
private List<CallbackListener> ls = new ArrayList<>();
private boolean completed = false;
@Override
public void addListener(CallbackListener listener) {
if(completed){//如果已完成,则立即执行
listener.operationComplete(this);
}else{
ls.add(listener);
}
}
@Override
public void notifyListener() {
for(CallbackListener l : ls){
l.operationComplete(this);
}
}
@Override
public void setComplete(boolean b) {
this.completed = b;
}
}
上面是基本组件,下面我们定义一个 被调用方的例子
public class A{
public Callback invoke(){
Callback callback = new DefaultCallback();
//用线程实现异步
new Thread(new Runnable(){
public void run(){
System.out.println("do something...");
callback.setComplete(true);
callback.notifyListener();
}
}).start();
return callback;
}
}
写一个测试程序
public class Test {
public static void main(String[] args) {
A a = new A();
Callback callback = a.invoke();
callback.addListener(new CallbackListener() {
@Override
public void operationComplete(Callback callBack) {
System.out.println("do callback...");
}
});
}
}
如果大家用这几段代码做了测试就能体会到,异步回调除了可以异步通知之外,还能保证代码在逻辑上的同步。
Netty中的实现
Netty中实现回调或者future通知的机制与上面的相似。
Netty中对Channel上IO操作都会立马返回并得到一个ChannelFuture引用,我们可以在ChannelFuture中注册监听 - ChannelFutureListener,这样我们就能在操作完成时获得通知。如下利用此机制实现在 成功连接 后的一些操作:
Channe channel = ...;
ChannelFuture future =
channel.connect(new InetSocketAddress("localhost",8848));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if(future.isSucess()){
System.out.println("do something...");
}else{
...
}
}
});
结束语
本文的重点在于中篇的异步回调,如果能明白了这个模式,也就明白了Netty中完全异步是怎么实现的。建议大家可以结合最后netty的例子调式下,这样才会有更深的理解。
下篇将会继续介绍 读 写事件在netty中是如何优雅处理的。
猜你喜欢
- 2024-11-19 你知道@Async 是怎么让方法异步执行的吗?
- 2024-11-19 Java 并发编程 11 - 异步执行框架 Executor
- 2024-11-19 Java中异步复用io
- 2024-11-19 JAVA异步方法笔记
- 2024-11-19 面试官:Redis分布式锁超时了,任务还没执行完怎么办?
- 2024-11-19 万能通用的异步实战方案,设计多线程,mq
- 2024-11-19 Java客户端Jedis 对Redis的几种调用方式包括事务、管道、分布式
- 2024-11-19 Dubbo 2.7新特性之异步化改造
- 2024-11-19 新手也能看懂的 SpringBoot 异步编程指南
- 2024-11-19 SpringBoot 异步编程
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)