官方文檔:
Interface ChannelFuture ------------------ Netty API Reference (4.0.54.Final)
The result of an asynchronous Channel I/O operation.
異步 Channel I/O操作執(zhí)行后所得的結果
All I/O operations in Netty are asynchronous. It means any I/O calls will return immediately with no guarantee that the requested I/O operation has been completed at the end of the call. Instead, you will be returned with a ChannelFuture instance which gives you the information about the result or status of the I/O operation.
Netty的所有I/O操作都是異步的癣漆。這意味著任何I/O調(diào)用都會立即返回結果,不保證請求的I/O操作能執(zhí)行到I/O函數(shù)的最后一條語句。相反,它會返回ChannelFuture實例告訴你此次I/O操作的結果和狀態(tài)碼。
A ChannelFuture is either uncompleted or completed. When an I/O operation begins, a new future object is created. The new future is uncompleted initially - it is neither succeeded, failed, nor cancelled because the I/O operation is not finished yet. If the I/O operation is finished either successfully, with failure, or by cancellation, the future is marked as completed with more specific information, such as the cause of the failure. Please note that even failure and cancellation belong to the completed state.
一個ChannelFuture只有兩種狀態(tài):完成和未完成。當一個I/O操作開始執(zhí)行,新的ChannelFuture對象就會被創(chuàng)建俄占。future對象初始化為未完成---既不是成功或失敗,也不是被取消剥汤,因為這個I/O操作還沒有完成颠放。如果I/O操作執(zhí)行成功、或執(zhí)行失敗吭敢、或被取消碰凶,future實例被標記為完成,而且會返回特定的信息鹿驼,如執(zhí)行失敗時返回失敗信息欲低。請注意即使是失敗或被取消,future仍屬于完成狀態(tài)畜晰。
Various methods are provided to let you check if the I/O operation has been completed, wait for the completion, and retrieve the result of the I/O operation. It also allows you to add ChannelFutureListeners so you can get notified when the I/O operation is completed.
Netty提供了多種方法讓你確認I/O是否已經(jīng)完成砾莱,還是等待完成,還是返回了I/O操作的結果凄鼻。同時腊瑟,你可以添加監(jiān)聽者 ChannelFutureListener來告知你I/O已經(jīng)完成聚假。
Prefer addListener(GenericFutureListener) to await()
It is recommended to prefer addListener(GenericFutureListener) to await() wherever possible to get notified when an I/O operation is done and to do any follow-up tasks.
每當你需要被告知I/O操作已完成并想接著做點什么事,建議用addListener(GenericFutureListener) 而不要用await()闰非。
addListener(GenericFutureListener) is non-blocking. It simply adds the specified ChannelFutureListener to the ChannelFuture, and I/O thread will notify the listeners when the I/O operation associated with the future is done. ChannelFutureListener yields the best performance and resource utilization because it does not block at all, but it could be tricky to implement a sequential logic if you are not used to event-driven programming.
addListener(GenericFutureListener) 是非阻塞的膘格。它可以很簡單地將ChannelFutureListener添加到ChannelFuture,然后I/O線程會提醒listener I/O完成财松。ChannelFutureListener有最好的性能和資源的充分利用瘪贱,因為它是完全非阻塞的。但假如你不熟悉事件驅(qū)動編程辆毡,你反而可能覺得實現(xiàn)連續(xù)邏輯會比較困難菜秦。
By contrast, await() is a blocking operation. Once called, the caller thread blocks until the operation is done. It is easier to implement a sequential logic with await(), but the caller thread blocks unnecessarily until the I/O operation is done and there's relatively expensive cost of inter-thread notification. Moreover, there's a chance of dead lock in a particular circumstance, which is described below.
相比之下,await()是阻塞方法舶掖。一旦調(diào)用球昨,調(diào)用者線程會一直阻塞,直到I/O操作完成眨攘。await()更容易實現(xiàn)連續(xù)邏輯褪尝,但它造成了I/O操作時不必要的線程阻塞,而且要實現(xiàn)線程間的通信需要很大的代價期犬。再者,在特定情況下還會發(fā)生死鎖避诽,下文將會提到龟虎。
Do not call await() inside ChannelHandler
The event handler methods in ChannelHandler are usually called by an I/O thread. If await() is called by an event handler method, which is called by the I/O thread, the I/O operation it is waiting for might never complete because await() can block the I/O operation it is waiting for, which is a dead lock.
事件處理函數(shù)經(jīng)常在ChannelHandler里面被I/O線程調(diào)用。如果await()被事件處理函數(shù)調(diào)用沙庐,事件處理函數(shù)又被I/O線程調(diào)用鲤妥,那么它(事件處理函數(shù))將一直等待永遠不會完成的I/O操作。因為await()可以阻塞它(事件處理函數(shù))一直等待的I/O操作拱雏,這就造成了死鎖棉安。
In spite of the disadvantages mentioned above, there are certainly the cases where it is more convenient to call await(). In such a case, please make sure you do not call await() in an I/O thread. Otherwise, BlockingOperationException will be raised to prevent a dead lock.
盡管有以上缺陷,但仍有某些特例調(diào)用await()會更便捷铸抑。在這種情況下贡耽,請確保你沒有在I/O線程調(diào)用await()。否則將會拋出BlockingOperationException異常以防止死鎖鹊汛。
Do not confuse I/O timeout and await timeout
The timeout value you specify with Future.await(long), Future.await(long, TimeUnit), Future.awaitUninterruptibly(long), or Future.awaitUninterruptibly(long, TimeUnit) are not related with I/O timeout at all. If an I/O operation times out, the future will be marked as 'completed with failure,' as depicted in the diagram above. For example, connect timeout should be configured via a transport-specific option:
你用Future.await(long)蒲赂,F(xiàn)uture.await(long, TimeUnit),F(xiàn)uture.awaitUniterruptibly(long)或Future.awaitUninterruptibly(long, TimeUnit) 等方法指定timeoue的值刁憋,跟I/O的timeout沒有一點關系滥嘴。如果I/O操作超時,ChannelFuture會被記為"執(zhí)行完畢至耻,結果:失敗"若皱,如前文第一張圖所示镊叁。舉個例子,連接超時應該通過傳遞特定參數(shù)來配置走触。