chapter19 Future和Promise
1. Future功能
Netty的Future都是与异步IO操作相关的,因此命名为ChannelFuture,代表其与Channel操作相关
ChannelFuture两种状态:
- uncompleted和completed
- 当开始一个IO操作时,一个新的ChannelFuture被创建,此时它处于uncompleted状态——非失败、非成功、非取消。一旦IO操作完成,将被设置成completed,其操作结果有三种可能:操作成功、 操作失败、操作被取消
- Netty强烈建议直接通过添加监听器的方式[GenericFutureListener接口]获取IO操作结果,或者进行后续的相关操作
- 当IO操作完成之后,IO线程会回调ChannelFuture中GenericFutureListener的operationComplete方法,并把ChannelFuture对象当作方法的入参。如果用户需要做上下文相关的操作,需要将上下文信息保存到对应的ChannelFuture中。
推荐通过GenericFutureListener代替ChannelFuture的get等方法的原因:
- 当进行异步IO操作时,完成的时间无法预测的,如果不设置超时时间,会导致调用线程长时间被阻塞,甚至挂死。而设置超时时间,时间又无法精确预测。利用异步通知机制回调是最佳的解决方案,性能也最优。
需要注意:不能在ChannelHandler中调用ChannelFuture的await()方法,会导致死锁。原因是发起IO操作之后,由IO线程负责异步通知发起IO操作的用户线程,如果IO线程和用户线程是同一个线程,就会导致IO线程等待自己通知操作完成,就会导致死锁。
异步IO操作有两类超时:一个是TCP层面,一个是业务逻辑层面。通常情况下业务逻辑超时时间应该大于IO超时时间,两者应该是包含关系。
- ChannleFuture超时并不代表着IO超时,意味着ChannelFuture超时,如果没有关闭连接资源,随后连接依旧可能会成功,会导致严重问题。
2. Promise功能介绍
- Promise是可写的Future,Future自身并没有写操作相关的接口,Netty通过Promise对Future进行扩展,用于设置IO操作的结果。
- Netty发起IO操作的时候,会创建一个新的Promise对象