目录
一、java.util.concurrent.Future
二、java.util.concurrent.FutureTask
三、io.netty.util.concurrent.Future
四、io.netty.channel.ChannelFuture
我们先看下netty 中ChannelHandler 类的diagrams
可以看到它最顶层是继承的jdk 的Future 接口。我们先分析下jdk 并发包下的Future接口
从这个类的注释中,我们可以了解到:
Future 类就是代表了异步计算的结果,这个接口的主要方法就是检查计算是否已完成,等待计算,然后返回计算结果。
当计算完成后,结果只能通过get方法返回;如果有必要会堵塞直到它计算完成。
可以通过cancel方法取消。增加的方法来判断任务是否正常完成或者被取消。一旦计算已经完成,计算不能被取消。
如果你想要使用Future 来取消,但是不提供一个可用的结果,你可以声明Futrue 的类型,但会返回null 作为一个基本任务的结果。
FutureTask 类是Futrue类的一个实现类,实现了Runnable接口,可以被Executor 执行。
一个可取消的异步计算,这个类提供了对Future 的基本实现。有对计算的启动和取消方法,查询计算是否已完成,以及返回计算的结果。
计算的结果只有在计算已完成后才能返回,如果计算没有完成,get方法会堵塞。一旦计算已经完成,计算不能被重启或取消。(除非计算是被runAndReset方法调用)
可以看到这个类中有表示计算执行的状态
private volatile int state;
private static final int NEW = 0;
private static final int COMPLETING = 1;
private static final int NORMAL = 2;
private static final int EXCEPTIONAL = 3;
private static final int CANCELLED = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED = 6;
在判断当前计算是否已完成等状态时,都是通过这个字段来进行判断。
可以看到这个Future 接口集成自jdk 的Futrue 接口
The result of an asynchronous operation
表示异步操作的结果。声明了一些接口方法。主要就是获取计算执行的状态,增加监听器等。
异步IO操作的结果。
Netty 里面的IO操作全部是异步的。这意味着,IO操作会立即返回,但是在调用结束时,无法保证IO操作已完成。取而代之,将会返回给你一个ChannelFuture 实例,提供IO操作的结果信息或状态。
一个ChannelFuture 要么是未完成,要么是已完成。当一个IO操作开始,一个新的future对象被创建。这个新的future 初始化未完成 - 它既不是成功,也不是失败,也不是被取消。因为IO操作还没有完全结束。如果IO操作已经完成,那它要么是成功,要么是失败,要么是被取消,这个future会被标记成已完成并伴随其他信息,比如失败的原因。请注意,即使是失败和被取消已归属于完成状态。
+---------------------------+
| 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 |
+---------------------------+
提供了各种各样的方法来让你检查IO操作是否已完成,等待完成,返回IO操作的结果。同时,也能让你增加ChannelFutureListener,这样当IO操作完成的时候,你就能获得通知。
推荐使用addListener 方法,而不是await()方法。后者是阻塞方法。