netty---sync,await
LOG.info("*************************WINDOWS系统*********************************");
//设置事件处理
serverBootstrap.childHandler(nettyServerInitializer);
windowFuture = serverBootstrap.bind(nettyConfig.getPort());
windowFuture.channel().closeFuture().sync();
netty启动的时候
windowFuture = serverBootstrap.bind(nettyConfig.getPort())方法后加sync,后边的代码是会被执行的,
但是
windowFuture.channel().closeFuture().sync();这个代码之后的代码不会被执行,比较迷惑 sync方法找到根里是如下源码
public Promise<V> sync() throws InterruptedException {
this.await();
this.rethrowIfFailed();
return this;
}
接下来是来自一位大牛的博客内容https://blog.csdn.net/benluobobo/article/details/53870347
Netty 学习 - 异步操作中的Future和Promise
本文继续介绍Netty的相关知识,主要讲解异步操作中的Future和Promise
由于Netty中的Future都是异步IO操作,结果是未知的,因此命名为ChannelFuture,表示跟Channel的操作有关
ChannelFuture提供了一系列不同于JDK Future的API,用于获取操作结果,添加事件监听器,取消IO操作,同步等待。
Netty强烈建议直接通过添加监听器的方式获取IO结果,而不是通过同步等待的方式
如果用户操作调用了sync或者await方法,会在对应的future对象上阻塞用户线程,例如future.channel().closeFuture().sync()
而最终触发future对象的notify动作都是通过eventLoop线程轮询任务完成的,例如对关闭的sync,因为不论是用户直接关闭或者eventLoop的轮询状态关闭,都会在eventLoop的线程内完成notify动作,所以不要在IO线程内调用future对象的sync或者await方法,因为应用程序代码都是编写的channelHandler,而channelHandler是在eventLoop的线程内执行的,所以是不能在channelHandler中调用sync或者await方法的
对于Future而言,提供的API有get与get(timeout) 前者是一直阻塞的get方法,后者带了超时时间,具体实现方式是在Future上执行wait方法,将当前运行线程进行阻塞,达到阻塞效果,而后通过eventLoop线程对Future对象进行notifyAll,保证唤醒阻塞的线程
而Future只有获取查询的API,类似于JDK中的Future,为了扩展对异步结果的写操作,Netty提供了Promise,继承于Future,可以用于设置IO操作的结果,在AbstratChannel的代码中可以看到对相关的IO操作都会新建Promise作为具体IO函数的参数,这样就能异步立即返回Promise,当IO操作后续发生异常或者完成时,将会设置promise的结果,在设置结果的过程中,包括以下三步
1 设置result的值
2 notifyAll,唤醒在本Promise上等待的线程
3 回调listener
下面以最常见的关闭等待操作为例,在大部分的网上例子中都会有如下的代码:
Channel channel = b.bind(8080).sync().channel();
channel.closeFuture().sync();
那么下面的channel.closeFuture().sync()实际是如何工作
channel.closeFuture()不做任何操作,只是简单的返回channel对象中的closeFuture对象,对于每个Channel对象,都会有唯一的一个CloseFuture,用来表示关闭的Future,
所有执行channel.closeFuture().sync()就是执行的CloseFuturn的sync方法,从上面的解释可以知道,这步是会将当前线程阻塞在CloseFuture上
一般来说,编写以上代码的都是在Main线程中用来启动ServerBootStrap的,所以Main线程会被阻塞,保证服务端Channel的正常运行
那么什么时候Main线程会被唤醒继续执行呢
在channel中有close方法,当调用close方法后,会按照pipeline.close - tail.close - head.close - unsafe.close - abstractChannel.doClose0
private void doClose0(ChannelPromise promise) {
try {
doClose();
closeFuture.setClosed();
safeSetSuccess(promise);
} catch (Throwable t) {
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
其中doClose方法是抽象方法,用来真正关闭IO连接,例如javaChannel.close
第二步则是用来处理CloseFuture的关闭,setClosed会执行trySuccess,这样就会在CloseFuture对象上执行notifyAll以及回调listener等,唤醒Main线程
第三步则是用来处理用户Future,前面说过在AbstratChannel的代码中可以看到对相关的IO操作都会新建Promise作为具体IO函数的参数,例如对于channel.close方法,分别有参数的方法和没有参数的方法,没有参数的方法实际在底层会自动new一个promise用来异步的返回结果,也可以在应用程序中主动编写一个Promise用来处理应用逻辑
在Promise对象上执行
@Override
public boolean trySuccess(V result) {
if (setSuccess0(result)) {
notifyListeners();
return true;
}
return false;
}
其中setSuccess0中会有 checkNotifyWaiters();的步骤,唤醒在该Promise对象上等待的线程,再notifyListeners进行回调Listener,完成设置动作
---------------------
作者:benluobo
来源:CSDN
原文:https://blog.csdn.net/benluobobo/article/details/53870347
版权声明:本文为博主原创文章,转载请附上博文链接!
netty---sync,await的更多相关文章
- Netty学习篇②
Channel.ChannelPipeline.ChannelHandlerContent发送数据的不同 // channel往回写数据 Channel channel = ctx.channel() ...
- Netty 源码解析(三): Netty 的 Future 和 Promise
今天是猿灯塔“365篇原创计划”第三篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源码解析(二): Netty 的 Channel 当前:Ne ...
- es6,es7,es8
概述 ES全称ECMAScript,ECMAScript是ECMA制定的标准化脚本语言.目前JavaScript使用的ECMAScript版本为ECMAScript-262. ECMAScript 标 ...
- JStorm开发经验+运维经验总结
1.开发经验总结 ——12 Sep 2014 · 8 revisions 在jstorm中, spout中nextTuple和ack/fail运行在不同的线程中, 从而鼓励用户在nextTuple里 ...
- ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用!因此,ES transport client可以同步调用也可以异步(不过底层的socket必然是异步实现)
ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用! 因此,ES tra ...
- netty底层是事件驱动的异步库 但是可以await或者sync(本质是future超时机制)同步返回 但是官方 Prefer addListener(GenericFutureListener) to await()
io.netty.channel 摘自:https://netty.io/4.0/api/io/netty/channel/ChannelFuture.html Interface ChannelFu ...
- 谈谈如何使用Netty开发实现高性能的RPC服务器
RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...
- 从netty-example分析Netty组件
分析netty从源码开始 准备工作: 1.下载源代码:https://github.com/netty/netty.git 我下载的版本为4.1 2. eclipse导入maven工程. netty提 ...
- Netty实现高性能RPC服务器优化篇之消息序列化
在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...
- Netty(六)UDP在netty中的使用
关于UDP的介绍,这里不在阐述.相比于TCP而言,UDP不存在客户端和服务端的实际链接,因此不需要为连接(ChannelPipeline)设置handler. 服务端: public void run ...
随机推荐
- 深入理解 Java 内存模型 JMM 与 volatile
Java 内存模型(Java Memory Model,简称 JMM)是一种抽象的概念,并不真实存在,它描述的是一组规范或者规则,通过这种规范定义了程序中各个变量(包括实例字段.静态字段和构成数组对象 ...
- ajax、反向ajax、jsonp详解
ajax详解 什么是ajax 其实ajax已经属于老技术了,现在几乎没人不会用了,在这里主要是把底层的东西给大家分享一下,以备应对装逼的面试官. ajax即“Asynchronous Javascri ...
- Spring Security自定义认证页面(动态网页解决方案+静态网页解决方案)--练气中期圆满
写在前面 上一回我们简单分析了spring security拦截器链的加载流程,我们还有一些简单的问题没有解决.如何自定义登录页面?如何通过数据库获取用户权限信息? 今天主要解决如何配置自定义认证页面 ...
- Redis的数据类型及使用场景
1.redis 的数据类型 String 字符串 Hash 哈希 List 列表 Set 集合 ZSet(Sorted Set) 有序集合 2.使用场景 2.1 String 用户token 可以用r ...
- IDEA常用快捷键Mac os和Windows对照--用到了就会更新
之前公司用了一段的MacBookPro,离职后自己入手了一台MacBookPro.但是现在的公司中使用的电脑是古老的win7,两个系统的键盘有些许差别,而且快捷键也略有不同.最近因为疫情影响,在家远程 ...
- MySQL 索引结构
谈到 MYSQL 索引服务端的同学应该是熟悉的不能再熟悉,新建表的时候怎么着都知道先来个主键索引,对于经常查询的列也会加个索引加快查询速度.那么 MYSQL 索引都有哪些类型呢?索引结构是什么样的呢? ...
- soso官方:搜索引擎的对检索结果常用的评测方法
http://www.wocaoseo.com/thread-188-1-1.html 很久很久以前,搜索引擎还不象今天的百花齐放,人们对它的要求较低,只要它能把互连网上相关的网站搜出来, ...
- C语言如何动态分配二维数组
C语言如何动态分配二维数组(转载) 原文链接:https://www.cnblogs.com/0xWitch/p/9314621.html 使用malloc().free()函数进行动态分配,这两个函 ...
- Python | 详解Python中的协程,为什么说它的底层是生成器?
今天是Python专题的第26篇文章,我们来聊聊Python当中的协程. 我们曾经在golang关于goroutine的文章当中简单介绍过协程的概念,我们再来简单review一下.协程又称为是微线程, ...
- Labview学习之路(十三)数组函数
本文章介绍一下函数选版中的数组函数,一眼看懂没什么特殊地方的就不说了 (一)数组大小 返回I32类型的数或者数组. 什么是I32类型?就是32位有符号整型, 有符号什么意思?就是在32位数据中最高做符 ...