Future 和 ChannelFuture


一、Future

Netty的Future接口繼承了JDK的Future接口,同時提供了更多的方法:

public interface Future<V> extends java.util.concurrent.Future<V> {
    boolean isSuccess();
    Throwable cause();
    Future<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);
    Future<V> removeListener(GenericFutureListener<? extends Future<? super V>> listener);
    Future<V> sync() throws InterruptedException;
    Future<V> await() throws InterruptedException;
    V getNow();
}

任務成功完成后isSuccess()返回true
任務執行過程中有異常,cause()會返回異常對象
任務被取消執行,父接口方法isCancelled返回true
以上3種情況isDone()均為true:

//任務完成
 if (task.isDone()) {
    if (task.isSuccess()) {
        // 成功
    } else if (task.isCancelled()) {
        // 被取消
    } else {
        // 異常
        System.out.print(task.cause())
    }
 }

wait和sync都會阻塞,並等待任務完成
getNow()不會阻塞,會立即返回,但任務尚未執行完成時,會返回null
addListener方法在當前Future對象中添加監聽器,當任務完成時,會通知所有的監聽器。

二、ChannelFuture

ChannelFuture繼承了Netty的Future接口,代表 Netty channel的I/O操作的執行結果。在Netty中所有的I/O操作都是異步的,會立即返回一個代表I/O操作的結果,即ChannelFuture。

在獲得執行結果時,推薦使用添加監聽器,監聽執行完成事件operaionCompleted,而不要使用await方法。在ChannelHandler中調用await,會造成死鎖。因為ChannelHandler中的方法通常是I/O線程調用的,再調用await會造成I/O阻塞。

 //錯誤
 @Override
 public void channelRead(ChannelHandlerContext ctx, Object msg) {
   ChannelFuture future = ctx.channel().close();
   future.awaitUninterruptibly();
   // Perform post-closure operation
   // ...
 }

 // 正確
 @Override
 public void channelRead(ChannelHandlerContext ctx, Object msg) {
   ChannelFuture future = ctx.channel().close();
   future.addListener(new ChannelFutureListener() {
       public void operationComplete(ChannelFuture future) {
           // Perform post-closure operation
           // ...
       }
   });
 }

即使是通過添加ChannelFutureListener的方式獲取執行結果,但要注意的是:回調方法operationComplete也是由I/O線程調用的,所以也不能在其中執行耗時任務。如必須,則啟用線程池執行。

ChannelFuture channelFuture = serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ServerInitializer())
                .bind(8899)
                .sync();

bind方法是異步的,其返回值是ChannelFuture類型。需要調用sync()同步方法,等待綁定動作執行完成。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM