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的更多相关文章

  1. Netty学习篇②

    Channel.ChannelPipeline.ChannelHandlerContent发送数据的不同 // channel往回写数据 Channel channel = ctx.channel() ...

  2. Netty 源码解析(三): Netty 的 Future 和 Promise

    今天是猿灯塔“365篇原创计划”第三篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源码解析(二): Netty 的 Channel 当前:Ne ...

  3. es6,es7,es8

    概述 ES全称ECMAScript,ECMAScript是ECMA制定的标准化脚本语言.目前JavaScript使用的ECMAScript版本为ECMAScript-262. ECMAScript 标 ...

  4. JStorm开发经验+运维经验总结

    1.开发经验总结  ——12 Sep 2014 · 8 revisions 在jstorm中, spout中nextTuple和ack/fail运行在不同的线程中, 从而鼓励用户在nextTuple里 ...

  5. ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用!因此,ES transport client可以同步调用也可以异步(不过底层的socket必然是异步实现)

    ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用! 因此,ES tra ...

  6. 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 ...

  7. 谈谈如何使用Netty开发实现高性能的RPC服务器

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...

  8. 从netty-example分析Netty组件

    分析netty从源码开始 准备工作: 1.下载源代码:https://github.com/netty/netty.git 我下载的版本为4.1 2. eclipse导入maven工程. netty提 ...

  9. Netty实现高性能RPC服务器优化篇之消息序列化

    在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...

  10. Netty(六)UDP在netty中的使用

    关于UDP的介绍,这里不在阐述.相比于TCP而言,UDP不存在客户端和服务端的实际链接,因此不需要为连接(ChannelPipeline)设置handler. 服务端: public void run ...

随机推荐

  1. Wireshark中遇到的epoch time

    使用Wireshark分析DNS时遇到的Epoch time 首先看一下Wireshark分析DNS的情况(如下图): 这是协议树的第一项,第一项中的第五行出现了Epoch Time,查阅资料之后才知 ...

  2. Spring Security-获取当前登录用户的详细信息

    在Spring框架里面,可以通过以下几种方式获取到当前登录用户的详细信息: 1. 在Bean中获取用户信息 Authentication authentication = SecurityContex ...

  3. 在string.replace中使用具名组匹配

    let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; let re = '2015-01-02'. r ...

  4. Project ACRN documentation

    Project ACRN documentation https://projectacrn.github.io/latest/index.html Virtio devices high-level ...

  5. 基于 abp vNext 微服务开发的敏捷应用构建平台 - 项目介绍

    缘起 目前使用ABP框架已经将近3年了,大大小小的项目也陆陆续续做了很多.由于现有信息系统的架构模式是在底层的技术平台上直接构建信息系统并采用技术主导,使用业务无关的编程工具来开发信息系统的缺陷使得系 ...

  6. Linux高频操作

    常用linux命令 查看文件.文件夹大小 du -hs <file/dir> 同时输出到控制台和文件 ./<program> 2>&1 | tee <log ...

  7. Linux教学资源服务器构建

    1. 需求分析 1.1 课题简介 随着计算机互联网的迅速发展,大多数学校已经实现教学的信息化,从传统的黑板教学方式转变为现阶段的多媒体教学,教学的资源,素材课件,甚至学生的作业也都实现数字化,为了实现 ...

  8. 区块链入门到实战(25)之以太坊(Ethereum) – 以太币单位

    以太币的主要单位是以太/Ether,即一个以太币,以太币的最小单位是wei. 以太币最小单位 wei 是以虚拟币先驱人物:戴伟 Wei Dai 命名,戴伟 W Dai 是一位兴趣广泛的密码学专家,他在 ...

  9. webgl实现径向模糊

    径向模糊简介 径向模糊,是一种从中心向外呈幅射状,逐渐模糊的效果. 因此径向模糊经常会产生一些中心的发散效果,在PS中同样也有径向模糊的滤镜效果. 径向模糊通常也称为变焦模糊.径向模糊(Radial ...

  10. Linux下如何知道是否有人在使坏?

    在 Linux 下查看用户的行为,不仅仅是网管要做的事,也是开发人员所应该具备的基本技能之一.为什么呢?因为有时其他同事在做一些很消耗资源的事情,比如在编译大型程序,可能会导致服务器变得很慢,从而影响 ...