Future 提供了另一种在操作完成时通知应用程序的方式。这个对象可以看作是一个异步操
作的结果的占位符;它将在未来的某个时刻完成,并提供对其结果的访问。
JDK 预置了 interface java.util.concurrent.Future,但是其所提供的实现,只
允许手动检查对应的操作是否已经完成,或者一直阻塞直到它完成。这是非常繁琐的,所以 Netty
提供了它自己的实现——ChannelFuture,用于在执行异步操作的时候使用。
ChannelFuture提供了几种额外的方法,这些方法使得我们能够注册一个或者多个
ChannelFutureListener实例。监听器的回调方法operationComplete(), 将会在对应的
操作完成时被调用 ①
// Does not block
。然后监听器可以判断该操作是成功地完成了还是出错了。如果是后者,我
们可以检索产生的Throwable。简而 言之 ,由ChannelFutureListener提供的通知机制消除
了手动检查对应的操作是否完成的必要。
每个 Netty 的出站 I/O 操作都将返回一个 ChannelFuture;也就是说,它们都不会阻塞。
正如我们前面所提到过的一样, Netty 完全是异步和事件驱动的。
示例代码:
public class ConnectExample {
private static final Channel CHANNEL_FROM_SOMEWHERE = new NioServerSocketChannel();
public static void connect() {
Channel channel = CHANNEL_FROM_SOMEWHERE; // 指向某个位置
// 不会阻塞,异步地连接到远程节点
ChannelFuture future = channel.connect(new InetSocketAddress("127.0.0.1", 8080));
// 注册一个ChannelFutureListener,以便在操作完成时获得通知
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
// 检查操作的状态
if (future.isSuccess()) {
// 如果操作是成功的,则创建一个ByteBuf 以持有数据
ByteBuf buffer = Unpooled.copiedBuffer("Hello", Charset.forName("UTF-8"));
// 将数据异步地发送到远程节点。返回一个ChannelFuture
ChannelFuture wf = future.channel().write(buffer);
// ...
} else {
// 如果发生错误,则访问描述原因的Throwable
Throwable cause = future.cause();
cause.printStackTrace();
}
}
});
}
public static void main(String[] args) throws IOException
{
ConnectExample.connect();
}
}
网友评论