netty 之 非同步處理雙子星io.netty.util.concurrent.Future與io.netty.util.concurrent.Promise

mazhongjia發表於2020-09-30

一、JDK的java.util.concurrent.Future

從這個類的註釋中,我們可以瞭解到:

Future 類就是代表了非同步計算的結果,這個介面的主要方法就是檢查計算是否已完成,等待計算,然後返回計算結果。

當計算完成後,結果只能通過get方法返回;如果有必要會堵塞直到它計算完成。

可以通過cancel方法取消。增加的方法來判斷任務是否正常完成或者被取消。一旦計算已經完成,計算不能被取消。

如果你想要使用Future 來取消,但是不提供一個可用的結果,你可以宣告Futrue 的型別,但會返回null 作為一個基本任務的結果。

FutureTask 類是Futrue類的一個實現類,實現了Runnable介面,可以被Executor 執行。

二、JDK的java.util.concurrent.FutureTask

  • 一個可取消的非同步計算,這個類提供了對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;
  • 在判斷當前計算是否已完成等狀態時,都是通過這個欄位來進行判斷。

三、Netty的io.netty.util.concurrent.Future

1、說明

Netty的【io.netty.util.concurrent.Future】擴充套件了【java.util.concurrent.Future】:

  • 保留jdk Future的若干阻塞行為的介面
  • 同時增加了【listener型別的介面】,通過監聽器可以讓非同步執行更加有效率(當非同步執行有結果時進行回撥)

2、io.netty.util.concurrent.Future繼承體系與方法如下

四、Netty的io.netty.channel.ChannelFuture

【io.netty.channel.ChannelFuture】又擴充套件了【io.netty.util.concurrent.Future】

  • 提供和一個Channel進行繫結(通過ChannelFuture的channel方法可以獲取對應的Channel物件)。
  • ChannelFuture的大部分介面都是Override的io.netty.channel.ChannelFuture
    • ①將型別具化成ChannelFuture
    • ②將引數GenericFutureListener的範型具化成   <? extends Future<? super Void>>,其中<? super Void>表示了一種沒有返回值的非同步呼叫:

4.1 ChannelFuture的狀態

ChannelFuture有兩種狀態:未完成(uncompleted)和完成(completed).
當令Channel開始一個I/O操作時,會建立一個新的ChannelFuture去非同步完成操作.
被建立時的ChannelFuture處於uncompleted狀態(非失敗,非成功,非取消);一旦ChannelFuture完成I/O操作,ChannelFuture將處於completed狀態,結果可能有三種:

  1. 操作成功
  2. 操作失敗
  3. 操作被取消(I/O操作被主動終止)
    需要關注ChannelFuture的其它屬性來獲取異常資訊。

下圖是 Netty API 中提供的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      |
                                      +---------------------------+

4.2 ChannelFutureListener監聽介面

ChannelFuture的get()方法獲取非同步操作的結果,但是切記一定要設定超時時間
Netty建議通過ChannelFutureListener介面執行非同步操作結束後的回撥

示例程式碼:

 @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
             // ...
         }
     });
 }

 另外,ChannelFuture允許新增一個或多個(移除一個或多個)ChannelFutureListener監聽介面,方法名:addListener(), addListeners(), removeListener(), removeListeners()

五、Netty的io.netty.util.concurrent.Promise

XXXX

 

相關文章