Netty中的Future
先看下Future的整个继承体系,还有一个ChannelFuture不在里面;

- Future<V>的V为异步结果的返回类型
- getNow 是无阻塞调用,返回异步执行结果,如果未完成那么返回null
- await 是阻塞调用,等到异步执行完成
- isSuccess 执行成功是否成功
- sync 阻塞调用,等待这个future直到isDone(可能由于正常终止、异常或取消而完成)返回true; 如果该future失败,重新抛出失败的原因。 和await区别就是返回结果不同,它返回一个Future对象,通过这个Future知道任务执行结果。
- 添加GenericFutureListener, 执行完成(future可能由于正常终止、异常或取消而完成)后调用该监听器。
privatefinalEventExecutor executor; //任务执行器privatevolatileObject result;//不仅仅是结果,也有可能是异常* 一个或多个监听器,可能是GenericFutureListener或者DefaultFutureListeners。如果是NULL有两种可能
* 1:没有添加触发器
* 2:已经出发了privateObject listeners;privateLateListeners lateListeners;privateshort waiters;
privatestaticboolean isDone0(Object result){return result !=null&& result != UNCANCELLABLE;}
publicboolean isSuccess(){Object result =this.result;if(result ==null|| result == UNCANCELLABLE){returnfalse;}return!(result instanceofCauseHolder);}
public V getNow(){Object result =this.result;if(result instanceofCauseHolder|| result == SUCCESS){returnnull;}return(V) result;}
@OverridepublicPromise<V> sync()throwsInterruptedException{await();rethrowIfFailed();returnthis;}
@OverridepublicPromise<V> await()throwsInterruptedException{if(isDone()){returnthis;}if(Thread.interrupted()){thrownewInterruptedException(toString());}synchronized(this){while(!isDone()){checkDeadLock();//判断当前线程是否是执行线程。如果是抛出异常。incWaiters();//添加等待个数try{wait();//释放锁,等待唤醒,阻塞该线程}finally{decWaiters();}}}returnthis;}
@Overridepublicboolean cancel(boolean mayInterruptIfRunning){Object result =this.result;if(isDone0(result)|| result == UNCANCELLABLE){returnfalse;}synchronized(this){// Allow only once.result =this.result;if(isDone0(result)|| result == UNCANCELLABLE){returnfalse;}this.result = CANCELLATION_CAUSE_HOLDER;if(hasWaiters()){notifyAll();}}notifyListeners();returntrue;}
/*** 该方法不需要异步,为啥呢* 1:这个方法在同步代码块里面调用,因此任何监听器列表的改变都happens-before该方法* 2:该方法只有isDone==true的时候调用,一但 isDone==true 那么监听器列表将不会改变*/privatevoid notifyListeners(){Object listeners =this.listeners;if(listeners ==null){return;}EventExecutor executor = executor();if(executor.inEventLoop()){finalInternalThreadLocalMap threadLocals =InternalThreadLocalMap.get();finalint stackDepth = threadLocals.futureListenerStackDepth();if(stackDepth < MAX_LISTENER_STACK_DEPTH){threadLocals.setFutureListenerStackDepth(stackDepth +1);try{if(listeners instanceofDefaultFutureListeners){notifyListeners0(this,(DefaultFutureListeners) listeners);}else{finalGenericFutureListener<?extendsFuture<V>> l =(GenericFutureListener<?extendsFuture<V>>) listeners;notifyListener0(this, l);}}finally{this.listeners =null;threadLocals.setFutureListenerStackDepth(stackDepth);}return;}}if(listeners instanceofDefaultFutureListeners){finalDefaultFutureListeners dfl =(DefaultFutureListeners) listeners;execute(executor,newRunnable(){@Overridepublicvoid run(){notifyListeners0(DefaultPromise.this, dfl);DefaultPromise.this.listeners =null;}});}else{finalGenericFutureListener<?extendsFuture<V>> l =(GenericFutureListener<?extendsFuture<V>>) listeners;execute(executor,newRunnable(){@Overridepublicvoid run(){notifyListener0(DefaultPromise.this, l);DefaultPromise.this.listeners =null;}});}}
@Overridepublicboolean setUncancellable(){Object result =this.result;if(isDone0(result)){return!isCancelled0(result);}synchronized(this){// Allow only once.result =this.result;if(isDone0(result)){return!isCancelled0(result);}this.result = UNCANCELLABLE;}returntrue;}privateboolean setFailure0(Throwable cause){if(cause ==null){thrownewNullPointerException("cause");}if(isDone()){returnfalse;}synchronized(this){// Allow only once.if(isDone()){returnfalse;}result =newCauseHolder(cause);if(hasWaiters()){notifyAll();}}returntrue;}privateboolean setSuccess0(V result){if(isDone()){returnfalse;}synchronized(this){// Allow only once.if(isDone()){returnfalse;}if(result ==null){this.result = SUCCESS;}else{this.result = result;}if(hasWaiters()){notifyAll();}}returntrue;}
CompleteFuture的几个子类是状态Promise
PromiseTask:该类继承了RunnableFuture接口,该类表示异步操作的结果也可以异步获得,类似JDK中的FutureTask,实例化该对象时候需要传一个Callable的对象,如果没有该对象可以传递一个Runnable和一个Result构造一个Callable对象。
privatestaticfinalclassRunnableAdapter<T>implementsCallable<T>{finalRunnable task;final T result;RunnableAdapter(Runnable task, T result){this.task = task;this.result = result;}@Overridepublic T call(){task.run();return result;}@OverridepublicString toString(){return"Callable(task: "+ task +", result: "+ result +')';}}
@Overridepublicvoid run(){try{if(setUncancellableInternal()){V result = task.call();setSuccessInternal(result);}}catch(Throwable e){setFailureInternal(e);}
IO调用会返回一个ChannelFuture的实例,通过该实例可以查看IO操作的结果和状态,
ChannelFuture有完成和未完成两种状态,当IO操作开始,就会创建一个ChannelFuture的实例,该实例初始是未完成状态,它不是成功,失败,或者取消,因为IO操作还没有完成,如果IO操作完成了那么将会有成功,失败,和取消状态,
* +---------------------------+
* | Completed successfully |
* +---------------------------+
* +----> isDone() = <b>true</b> |
* +--------------------------+ | | isSuccess() = <b>true</b> |
* | Uncompleted | | +===========================+
* +--------------------------+ | | Completed with failure |
* | isDone() = <b>false</b> | | +---------------------------+
* | isSuccess() = false |----+----> isDone() = <b>true</b> |
* | isCancelled() = false | | | cause() = <b>non-null</b> |
* | cause() = null | | +===========================+
* +--------------------------+ | | Completed by cancellation |
* | +---------------------------+
* +----> isDone() = <b>true</b> |
* | isCancelled() = <b>true</b> |
* +---------------------------+
该类提供了很多方法用来检查IO操作是否完成,等待完成,和接受IO操作的结果。还可以添加ChannelFutureListener的监听器,这样IO操作完成时就可以得到提醒
* 强烈建议使用addListener而不是await。
* addListener是非阻塞的,它简单的添加指定的ChannelFutureListener到ChannelFuture中,
* IO线程将在当绑定在这个future的IO操作完成时,触发这个触发器,优点是提高效率和资源的利用率
* await()是一个阻塞方法,一旦调用,调用线程将会阻塞直到IO操作完成。优点是容易实现顺序逻辑
Netty中的Future的更多相关文章
- Netty 中的异步编程 Future 和 Promise
Netty 中大量 I/O 操作都是异步执行,本篇博文来聊聊 Netty 中的异步编程. Java Future 提供的异步模型 JDK 5 引入了 Future 模式.Future 接口是 Java ...
- Netty中的连接管理
连接管理是我们首先需要关注的,检测空闲连接以及超时对于及时释放资源来说是至关重要的.由于这是一项常见的任务,Netty特地为它提供了几个ChannelHandler实现. 用于空闲连接以及超时的Cha ...
- Reactor 模式在Netty中的应用
Reactor 模式在Netty中的应用 典型的Rector模式 mainReactor 服务端创建成功后,会监听Accept操作,其中ServerSocketchannel中的PipeLine中现在 ...
- Netty(六):Netty中的连接管理(心跳机制和定时断线重连)
何为心跳 顾名思义, 所谓心跳, 即在TCP长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线, 以确保 TCP 连接的有效性. 为什么需要心跳 因为网络的不可靠性, 有可 ...
- Netty中的那些坑
Netty中的那些坑(上篇) 最近开发了一个纯异步的redis客户端,算是比较深入的使用了一把netty.在使用过程中一边优化,一边解决各种坑.儿这些坑大部分基本上是Netty4对Netty3的改进部 ...
- netty中的websocket
使用WebSocket 协议来实现一个基于浏览器的聊天室应用程序,图12-1 说明了该应用程序的逻辑: (1)客户端发送一个消息:(2)该消息将被广播到所有其他连接的客户端. WebSocket 在从 ...
- Netty中NioEventLoopGroup的创建源码分析
NioEventLoopGroup的无参构造: public NioEventLoopGroup() { this(0); } 调用了单参的构造: public NioEventLoopGroup(i ...
- netty中的发动机--EventLoop及其实现类NioEventLoop的源码分析
EventLoop 在之前介绍Bootstrap的初始化以及启动过程时,我们多次接触了NioEventLoopGroup这个类,关于这个类的理解,还需要了解netty的线程模型.NioEventLoo ...
- Netty中的ChannelFuture和ChannelPromise
在Netty使用ChannelFuture和ChannelPromise进行异步操作的处理 这是官方给出的ChannelFutur描述 * | Completed successfully | * + ...
随机推荐
- np.unique 的实现
1. 简单实现 import numpy as np def unique(ar): perm = ar.argsort() aux = ar[perm] flag = np.concatenate( ...
- wpf中将string格式的颜色转换成color类型
wpf中Brushes有很多对应的颜色,先盗张图,每个颜色对于的名称和ARGB值有了,问题是有时候我们取到的颜色是ARGB值,而且是string类型的,该怎么转换成color呢,只有转换成color之 ...
- Linux之时间、地点、人物、事件、情节
时间 date 显示当前时间 time cmd 显示 cmd的运行时间 地点 locate 根据文件名,迅速找到文件.基于系统构建的索引 find 根据各种规则找到文件,更强大,但比较慢 wherei ...
- CF884D:Boxes And Balls
浅谈\(Huffman\)树:https://www.cnblogs.com/AKMer/p/10300870.html 题目传送门:https://codeforces.com/problemset ...
- loj 2542 随机游走 —— 最值反演+树上期望DP+fmt
题目:https://loj.ac/problem/2542 因为走到所有点的期望就是所有点期望的最大值,所以先最值反演一下,问题变成从根走到一个点集任意一点就停止的期望值: 设 \( f[x] \) ...
- C# Application Excel TreeView
三章 应用 20节客户表登陆 //动软--单表--Models --新建.net项目--简单三层管理--DBUtity--DbHelper.cs 21节客户表数据读取 增加 CEnterprise(企 ...
- Hibernate基础(一)
Hibernate是ORM开源组件 源码:http://sourceforge.net/projects/hibernate/ 1.Hibernate的配置文件. 默认配置文件: hibernate. ...
- Anti-pattern(反模式)
常见的与“直觉”相背离的 anti-pattern 产生的实际原因是我们没有深入全面地考虑问题. 即只关注到自己关心的方面,忽略了其他重要的.恰好起相反作用的因素. 所以这个“直觉”是不成熟.不全面的 ...
- 机器学习:集成学习(Soft Voting Classifier)
一.Hard Voting 与 Soft Voting 的对比 1)使用方式 voting = 'hard':表示最终决策方式为 Hard Voting Classifier: voting = 's ...
- Python:函数变量的使用
1.上层函数不能直接使用其嵌套函数的变量: def func1(x, y): z = x + y def func2(): m = 3 z += m return z print(func1(1, 2 ...