目录
- 一、 Netty Future 与 Promise —— 异步世界的“信使”与“传话筒”🚀
- 1、 理解 Netty Future
- 2、 理解 Netty Promise
- 二、 代码案例解读💻
- 例1:同步处理任务成功👍
- 例2:异步处理任务成功📲
- 例3:同步处理任务失败(sync/get )❌
- 例4:同步处理任务失败( await )❌
- 例5:异步处理任务失败📵
- 例6:await 死锁检查⚠️
- 三、 总结✨
🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解 Java的 NIO 请看 : NIO,看完你就懂了!
其他优质专栏: 【🎇SpringBoot】【🎉多线程】【🎨Redis】【✨设计模式专栏(已完结)】…等
如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning
下面让我带着你进入 Netty 异步世界的奇妙乐园,用幽默风趣的语言详细讲解一下 Netty 的 Future 和 Promise 在整个异步处理中的“神圣角色”。
一、 Netty Future 与 Promise —— 异步世界的“信使”与“传话筒”🚀
了解Netty请看:【Netty篇】幽默的讲解带你入门 Netty !建议收藏
1、 理解 Netty Future
在 Java 的异步世界中,JDK 提供了 Future 接口,用来表示某个异步任务在未来会返回一个结果。然而,Netty 的 Future 可不是普通的“邮差”,它继承了 JDK Future 的功能,并增加了更多炫酷的异步操作功能。对比来看,JDK 的 Future 就像是一个只能被动等待包裹送达的普通快递📦,而 Netty 的 Future 则相当于可以主动接收短信通知📱、还可以添加回调函数,随时告诉你“包裹已妥投”或者“出错啦”的智能快递员!
Netty Future 的主要特点:
- 非阻塞查看结果:通过
getNow()
方法,你可以在不等待结果的情况下查看当前任务是否已经有了结果(还没到货时返回null
)。 - 同步等待与异步回调:支持通过
await()
或sync()
方法来同步等待任务完成;同时还支持添加监听器addListener()
,以便任务一完成就触发回调通知你任务成功还是失败。 - 判断状态:有
isSuccess()
和cause()
方法,前者判断任务是否顺利完成,后者获取失败的原因。
简单说,Netty Future 就是那个既可以告诉你“嗯,任务完成啦”,又可以让你“不用天天刷快递状态”的智能信使。😉
2、 理解 Netty Promise
Promise 则是在 Netty Future 的基础上进一步增强的角色。它不仅继承了 Netty Future 的所有技能,还扮演了一个“任务结果容器”的角色 —— 专门用来在不同线程间传递结果。可以把 Promise 想象成一个纸箱📦,你可以把处理结果(无论是成功的小礼物🎁还是失败的挫败感😓)封装进去,然后交给异步任务的“快递员”去传递给等待的那一方。
Promise 的独有能力:
- 设置结果:通过
setSuccess()
和setFailure()
方法来主动设置操作的成功或失败结果,就像你在邮寄包裹时在包裹上标注“送达啦”或“出错啦”。 - 脱离任务独立存在:它不强绑定在一个真实任务上,而是单纯作为信息传递的容器,方便两个线程之间进行沟通。
使用 Netty Promise 时,你完全可以自如地控制结果的传递,这就使得异步处理不再是“看天吃饭”,而像是有了明确的预报系统!🔮
二、 代码案例解读💻
让我们来看几个文件中提供的代码示例,看看 Netty Future 和 Promise 怎么在实际运作中“发威”的!
了解EventLoop请看:【Netty篇】EventLoopGroup 与 EventLoop 详解
例1:同步处理任务成功👍
在这个例子中,我们通过 DefaultPromise
提交了一个异步任务,该任务经过 1 秒后将结果 10 设置为成功,并分别调用 getNow()
(非阻塞获取结果)和 get()
(阻塞获取结果)。
DefaultEventLoop eventExecutors = new DefaultEventLoop();
DefaultPromise<Integer> promise = new DefaultPromise<>(eventExecutors);
eventExecutors.execute(() -> {
try {
Thread.sleep(1000); //休眠 1 秒
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("set success, {}", 10);
promise.setSuccess(10);
});
log.debug("start...");
log.debug("{}", promise.getNow()); // 此时还未产生结果,输出 null
log.debug("{}", promise.get());
输出结果
幽默点评:
就好比你下单了快递,一开始查快递状态发现还是“快递未到(null)”,1 秒后短信一来,“包裹 10 已送达”,你终于能开心地签收啦!🎉
例2:异步处理任务成功📲
此示例演示了如何通过 addListener()
添加一个异步回调,让你不用一直守着电脑,任务一完成,立刻收到通知。
DefaultEventLoop eventExecutors = new DefaultEventLoop();
DefaultPromise<Integer> promise = new DefaultPromise<>(eventExecutors);
// 注册回调监听器,当任务完成时异步通知
promise.addListener(future -> {
log.debug("{}", future.getNow());
});
// 1 秒后设置成功结果
eventExecutors.execute(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("set success, {}", 10);
promise.setSuccess(10);
});
log.debug("start...");
输出结果
幽默点评:
你注册了短信通知,1 秒后快递送到,你的手机立刻震动:“包裹 10 到达啦!”你再也不用时不时刷新查询界面啦。😎
例3:同步处理任务失败(sync/get )❌
通过 get()
或 sync()
获取结果时,若任务失败会抛出异常(就像快递因地址错误而无法送达,结果直接抛出异常包裹)。
DefaultEventLoop eventExecutors = new DefaultEventLoop();
DefaultPromise<Integer> promise = new DefaultPromise<>(eventExecutors);
eventExecutors.execute(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
RuntimeException e = new RuntimeException("error...");
log.debug("set failure, {}", e.toString());
promise.setFailure(e);
});
log.debug("start...");
log.debug("{}", promise.getNow());
promise.get(); // sync() 同样会将异常抛出
输出结果
幽默点评:
就像你急着签快递,结果包裹因为地址错误直接让你崩溃,异常也随之抛出
例4:同步处理任务失败( await )❌
采用 await()
方法等待任务完成,但不会抛出异常,你需要主动判断成功还是失败,通过 isSuccess()
判断并获取错误原因。
DefaultEventLoop eventExecutors = new DefaultEventLoop();
DefaultPromise<Integer> promise = new DefaultPromise<>(eventExecutors);
eventExecutors.execute(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
RuntimeException e = new RuntimeException("error...");
log.debug("set failure, {}", e.toString());
promise.setFailure(e);
});
log.debug("start...");
log.debug("{}", promise.getNow());
promise.await(); // 等待任务完成但不抛出异常
log.debug("result {}", (promise.isSuccess() ? promise.getNow() : promise.cause()).toString());
输出结果:
幽默点评:
这个例子使用 await
温柔不少,等待结束后你主动检查状态,发现“出错啦”,然后淡定地拿出纸笔记录问题。✍️
例5:异步处理任务失败📵
这段代码与例2类似,不过任务失败后通过添加监听器异步获取错误结果。
DefaultEventLoop eventExecutors = new DefaultEventLoop();
DefaultPromise<Integer> promise = new DefaultPromise<>(eventExecutors);
// 设置监听器,异步处理
promise.addListener(future -> {
log.debug("result {}", (promise.isSuccess() ? promise.getNow() : promise.cause()).toString());
});
eventExecutors.execute(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
RuntimeException e = new RuntimeException("error...");
log.debug("set failure, {}", e.toString());
promise.setFailure(e);
});
log.debug("start...");
输出结果:
幽默点评:
这就像你设置了短信通知,当快递因故“送达失败”时,你立刻收到消息:“出问题啦:error…”,整个过程迅速而高效!📉
例6:await 死锁检查⚠️
这个例子特别有趣,它展示了在同一个线程中如果调用 await()
会触发死锁检查,抛出 BlockingOperationException
。
DefaultEventLoop eventExecutors = new DefaultEventLoop();
DefaultPromise<Integer> promise = new DefaultPromise<>(eventExecutors);
eventExecutors.submit(() -> {
System.out.println("1");
try {
promise.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("2");
});
eventExecutors.submit(() -> {
System.out.println("3");
try {
promise.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("4");
});
输出结果:
幽默点评:
这段代码就像在一个派对上,有人非要一直守着快递,结果被主持人发现这是在“自缠绕”,直接抛出异常告诉他:“别傻等啦,你自己等死吧!”😂 从侧面告诉你,await()
在某些情况下是不能乱用的,要小心死锁风险!
三、 总结✨
通过上述讲解和多个幽默的代码示例,我们可以看到:
- Netty Future 为我们提供了既能同步等待又能异步回调的能力,让我们不用像 JDK 的 Future 那样对快递死盯一眼。
- Promise 则在 Future 的基础上增加了主动设置任务结果的功能,充当了任务结果在不同线程间“传递包裹”的容器,无论是成功的小礼物还是失败的提示,都能及时传达!
- 文件中的各个实例充分展示了如何处理任务成功与失败的不同场景,并且提醒我们要小心使用
await()
,以免因死锁检查而被“暴击”!😅
希望这份充满趣味、表情丰富且详细的讲解能够帮助你深入理解 Netty 中 Future 与 Promise 的奥秘,在今后的异步开发中用得得心应手、畅快如风!🌬️