xx单位网站建设方案,网站备案地区名,u盘做网站,医馆网站建设方案文章目录 前言一、JDK 的 Future 接口二、Netty 的 Future 接口三、ChannelFuture 接口总结 前言
回顾Netty系列文章#xff1a;
Netty 概述#xff08;一#xff09;Netty 架构设计#xff08;二#xff09;Netty Channel 概述#xff08;三#xff09;Netty Channel… 文章目录 前言一、JDK 的 Future 接口二、Netty 的 Future 接口三、ChannelFuture 接口总结 前言
回顾Netty系列文章
Netty 概述一Netty 架构设计二Netty Channel 概述三Netty ChannelHandler四ChannelPipeline源码分析五字节缓冲区 ByteBuf 六上字节缓冲区 ByteBuf七下Netty 如何实现零拷贝八Netty 程序引导类九Reactor 模型十工作原理详解十一Netty 解码器十二Netty 编码器十三Netty 编解码器十四自定义解码器、编码器、编解码器十五
JDK 中提供了 Future 接口Future 代表了一个异步处理的结果。 Netty 中对 JDK 的 Future 做了扩展。 为了深入了解这两者的不同点下面我们就来分析这两者的源码。
一、JDK 的 Future 接口
Future 接口提供了一些方法检查是否计算完毕例如等待计算完毕获取计算结果的方法。当计算完毕之后只能通过 get 方法获取结果或者一直阻塞等待计算的完成。取消操作可以通过 cancel 方法。另外也提供了 isDone 方法用于检测是正常完成还是被取消终止。 需要注意的是当 Future 的计算完成后不能进行取消操作。 Future 的核心源码如下
public interface FutureV {/*** 用来取消任务取消成功则返回true取消失败则返回false。* mayInterruptIfRunning参数表示是否允许取消正在执行却没有执行完毕的任务设为true则表示可以取消正在执行过程中的任务。* 如果任务已完成则无论mayInterruptIfRunning为true还是false此方法都返回false即如果取消已经完成的任务会返回false* 如果任务正在执行若mayInterruptIfRunning设置为true则返回true若mayInterruptIfRunning设置为false则返回false* 如果任务还没有执行则无论mayInterruptIfRunning为true还是false肯定返回true。*/boolean cancel(boolean mayInterruptIfRunning);/*** 表示任务是否被取消成功如果在任务正常完成前被取消成功则返回true*/boolean isCancelled();/*** 表示任务是否已经完成若任务完成则返回true*/boolean isDone();/*** 获取执行结果如果最终结果还没得出该方法会产生阻塞直到任务执行完毕返回结果*/V get() throws InterruptedException, ExecutionException;/*** 获取执行结果如果在指定时间内还没获取到结果则抛出TimeoutException*/V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
}在上面的接口定义中可以知道jdk 中的 Future 无论结果是成功、失败还是取消都用 isdone() 来检测而且无法区分到底是正常成功了还是异常终止了。因此在 Netty 中对 jdk 的 Future 做了扩展。
二、Netty 的 Future 接口
核心源码如下
public interface FutureV extends java.util.concurrent.FutureV {//异步操作完成且正常终止boolean isSuccess();//异步操作是否可以取消boolean isCancellable();//异步操作失败的原因Throwable cause();//添加一个监听异步操作完成时调用FutureV addListener(GenericFutureListener? extends Future? super V var1);FutureV addListeners(GenericFutureListener? extends Future? super V... var1);//移除监听者FutureV removeListener(GenericFutureListener? extends Future? super V var1);FutureV removeListeners(GenericFutureListener? extends Future? super V... var1);//阻塞直到异步操作完成FutureV sync() throws InterruptedException;FutureV syncUninterruptibly();//阻塞直到异步操作完成FutureV await() throws InterruptedException;FutureV awaitUninterruptibly();boolean await(long var1, TimeUnit var3) throws InterruptedException;boolean await(long var1) throws InterruptedException;boolean awaitUninterruptibly(long var1, TimeUnit var3);boolean awaitUninterruptibly(long var1);//非阻塞地返回异步结果如果尚未完成返回 nullV getNow();boolean cancel(boolean var1);
}Netty 中的 Future 相对于jdk 中的 Future 做了以下几个方面的扩展。
操作完成的结果做了区分分为 sucess 、fail、canceled 三种。 通过 addListeners() 方法可以添加回调操作即触发或者完成时需要进行的操作。 sync()和await()可以以阻塞的方式等待异步完成。 getNow() 可以获取异步操作的结果如果还未完成则返回 null 。
三、ChannelFuture 接口
在 Netty 中ChannelFuture 表示 Channel 的异步 I/O 操作的结果。 ChannelFuture 的核心源码如下
public interface ChannelFuture extends FutureVoid {Channel channel();ChannelFuture addListener(GenericFutureListener? extends Future? super Void var1);ChannelFuture addListeners(GenericFutureListener? extends Future? super Void... var1);ChannelFuture removeListener(GenericFutureListener? extends Future? super Void var1);ChannelFuture removeListeners(GenericFutureListener? extends Future? super Void... var1);ChannelFuture sync() throws InterruptedException;ChannelFuture syncUninterruptibly();ChannelFuture await() throws InterruptedException;ChannelFuture awaitUninterruptibly();boolean isVoid();
}从上述源码可以看到ChannelFuture 接口基本上继承自 Netty 的 Future 接口。 在 Netty 中所有的 I/O 操作都是异步的意味着很多的 I/O 操作被调用过后会立刻返回并且不能保证 I/O请求操作被调用后计算完毕替代它的是返回一个当前 I/O 操作状态和结果信息的 ChannelFuture 实例。 一个 ChannelFuture 要么是完成的要么是未完成的。当一个 I/O 操作开始时会创建一个 Future 对象Future 初始化时为完成的状态它既不是成功也不是失败也不是被取消。因为 I/O 操作还没有完全结束。如果 I/O 操作已经完成那它要么是成功要么是失败要么是被取消这个 future 会被标记成已完成并伴随其他信息比如失败的原因。 下图展示了 ChannelFuture 从未完成到完成的所有场景的状态变化。 ---------------------------| Completed successfully |------------------------------- isDone() true |-------------------------- | | isSuccess() true || Uncompleted | | -------------------------- | | Completed with failure || isDone() false | | ---------------------------| isSuccess() false |-------- isDone() true || isCancelled() false | | | cause() non-null || cause() null | | -------------------------- | | Completed by cancellation || ------------------------------- isDone() true || isCancelled() true |---------------------------ChannelFuture 提供了各种各样的方法来检查 I/O 操作是否已完成等待完成返回 I/O 操作的结果。同时也能让你增加ChannelFutureListener这样当 I/O 操作完成的时候你就能获得通知。 推荐优先使用addListener(GenericFutureListener)方法而不是await()方法。在可能的情况下这样就能在 I/O 操作完成时收到通知并且可以去做后续的任务处理。 addListener(GenericFutureListener) 本身是非阻塞的它会添加一个指定的ChannelFutureListener 到ChannelFuture并且 I/O 线程完成对应的操作将会通知监听器ChannelFutureListener也会提供最好的性能和资源利用率因为它永远不会阻塞但是如果不是基于事件编程它可能在顺序逻辑上存在棘手的问题。 相反的await()是一个阻塞的操作一旦被调用调用者线程在操作完成之前的阻塞的。
总结
以上我们分析了 JDK 提供的 Future 以及 Netty 的 Future 接口下节我们来分析 Netty 中的 PromisePromise是可写的 Future, Future 自身并没有写操作相关的接 Netty 通过 Promise对 Future进行扩展用于设置 I/O 操作的结果。