有关wakeup变量的使用有一下几个地方(这里只使用netty普通任务举例,不讨论定时任务)

部分1,NioEventLoop.select()

             if (hasTasks() && wakenUp.compareAndSet(false, true)) {selector.selectNow();selectCnt = 1;break;}int selectedKeys = selector.select(timeoutMillis);selectCnt ++;if (selectedKeys != 0 || oldWakenUp || wakenUp.get() || hasTasks() || hasScheduledTasks()) {break;}

部分2 NioEventLoop.run()

         select(wakenUp.getAndSet(false));if (wakenUp.get()) {selector.wakeup();}

部分3 NioEventLoop.wakeup()

   protected void wakeup(boolean inEventLoop) {if (!inEventLoop && wakenUp.compareAndSet(false, true)) {selector.wakeup();}}

1,2是reactor线程进行操作的方法 3是用户线程操作的方法
方法三比较好理解,就是在添加完一个任务后,去修改这个wakeup变量,然后去唤醒这个reactor线程

首先关注2,值得注意的是getAndSet返回的是修改之前的值,但是在这个select(wakenUp.getAndSet(false))之后又调用了一次selector.wakeup(); 为什么要这样做呢???

举例:

情况一
wakeup此时为默认值,但是现在用户线程在select(wakenUp.getAndSet(false)) 之前 修改wakeup为 true,调用了 wakeup()
此时传入select(wakenUp.getAndSet(false))的参数oldwakeup为 true ,wake的最新值,笔者称为newwakeup 这里为 false
因为用户线程调用了wakeup(),所以阻塞的select 方法不会阻塞
所以成功的没有进过阻塞进入break 因为没有阻塞,这种情况我称为唤醒成功

情况二
但是现在用户线程在select(wakenUp.getAndSet(false)) 之后 修改wakeup会失败,wakeup()不会调用
select(wakenUp.getAndSet(false))的参数oldwakeup为 false,newwakeup 为true
在部分1中if (hasTasks() && wakenUp.compareAndSet(false, true)) 这个判断会进入,然后调用了一次selectNow(),然后就break了
没有阻塞,唤醒成功

以上两中情况,针对的是第一次遍历执行
下面进入第二次遍历执行
当上面的情况被唤醒后,就会来到 if (wakenUp.get()) 这个判断,这里如果是被唤醒过来的,这里就会为true,又调用了一次wakeup
那么当再次进入oldwakeup为true,newwakeup为false,所以又重复了第一次遍历中的第一种情况,那么为什么要这么做???
加入netty在第二次遍历的时候又进来的一个任务呢?此时是没有办法调用到wakeup()这个方法的,因为调用这个方法之前有一个判断
wakenUp.compareAndSet(false, true),这个判断不会通过,而部分2中的wakeup()就是解决这个情况的

对于后面的遍历,如果没有设计到唤醒操作,那么oldwakeup 和 newwakeup都是false,netty就会进入正常的轮询了

那么现在又有一个问题,为什么需要使用到wakeup这个变量?
通过这个变量的类型可以知道 wakeup 是 AtomicBoolean,所以一定是为了解决并发问题的,如果说多个线程都需要唤醒操作本来是需要执行多次wakeup()这个操作的,但是wakeup()是个耗时的操作,所以使用到AtomicBoolean的compareAndSet(expect, update)方法,使得多次wakeup()都合并成一个wakeup()

netty之wakeup详解相关推荐

  1. Netty之Bootstrap详解

    本文来重点说下Bootstrap 文章目录 概述 Boostrap类 引导客户端和无连接协议Booststrap 引导服务端ServerBootstrap 本文小结 概述 在了解 ChanelPipe ...

  2. 六个月离职空档期获得足够时间反思自我+常见Netty面试题详解

    前言 疫情期我离职了,在这个时间离职也是很无奈.但这次的经历却让我有了一个认真反思的机会. 回顾前两年的工作经历,每天忙忙碌碌,看似解决了很多问题,也积累了很多经验,但实际都是一些浅层次的东西,只不过 ...

  3. Netty 教程 – ByteBuf详解

    ByteBuffer存在的问题 ByteBuffer是JDK1.4中提供的java.nio.Buffer, 在内存中预留指定大小的存储空间来存放临时数据,其他Buffer的子类有:CharBuffer ...

  4. Netty 教程 – 解码器详解

    TCP以流的方式进行数据传输,上层的应用为了对消息进行区分,往往采用如下方式 固定消息长度,累计读取到长度和定长LEN的报文后,就认为读取到了个完整的消息,然后将计数器位置重置在读取下一个报文内容 将 ...

  5. Netty之ByteBuf详解

    1. ByteBuf的创建 在Netty中,有一个比较常见的对象ByteBuf,它其实等同于Java Nio中的ByteBuffer,但是ByteBuf对Nio中的ByteBuffer的功能做了很作增 ...

  6. netty 之 telnet HelloWorld 详解

    2019独角兽企业重金招聘Python工程师标准>>> 依赖工具 Maven Git JDK IntelliJ IDEA 源码拉取 从官方仓库 https://github.com/ ...

  7. Netty详解(五):Netty TCP粘包 拆包

    1. 概述 无论是服务端还是客户端,我们读取或者发送消息的时候,都需要考虑TCP底层的粘包和拆包机制.下面我们来通过Netty来详解TCP底层的粘包和拆包机制. 2. TCP底层的粘包和拆包机制 TC ...

  8. netty系列之:netty中各不同种类的channel详解

    文章目录 简介 ServerChannel和它的类型 Epoll和Kqueue AbstractServerChannel ServerSocketChannel ServerDomainSocket ...

  9. netty系列之:netty中的Channel详解

    文章目录 简介 Channel详解 异步IO和ChannelFuture Channel的层级结构 释放资源 事件处理 总结 简介 Channel是连接ByteBuf和Event的桥梁,netty中的 ...

  10. netty系列之:netty中的ByteBuf详解

    文章目录 简介 ByteBuf详解 创建一个Buff 随机访问Buff 序列读写 搜索 其他衍生buffer方法 和现有JDK类型的转换 总结 简介 netty中用于进行信息承载和交流的类叫做Byte ...

最新文章

  1. [置顶] 决策树绘图(二)
  2. P1634 禽兽的传染病
  3. SimpleDateFormat 格式图
  4. Chrome Native Client 原理
  5. 围棋经典棋谱_秀秀老师:茶艺师也要学好围棋
  6. 万丰科技机器人排名_2020年全国机器人企业数量大排名(省份榜|9月)
  7. 实现前后端数据交互方法汇总
  8. 如果数据库也有一个元宇宙,应该会是什么样子?
  9. 今天的天气好热哦!!!
  10. 前端汉字encode_js编码转码中文
  11. 服务器怎么开启lldp协议,修改服务器lldp的mac地址
  12. 迅雷 应版权方要求,文件无法下载 解决方法
  13. “离职同事在工作群抢红包被踢”:学会退群,是职场人的基本修养
  14. 世界互联网大会马云演讲实录
  15. C#利用QRCode动态生成自定义二维码图片
  16. 分步:配置 IPAM 以管理 IP 地址空间
  17. 【控制】鲁棒性 H2 H无穷
  18. wordpress二次元主题
  19. 网友形容丑的50种搞笑方式(转载)
  20. 【渝粤题库】陕西师范大学200551 英语语音

热门文章

  1. Vue移动端H5手势缩放滚动拖拽插件Easyscroller
  2. 百度快照投诉技巧案例分析百度快照就是这样刷出来的
  3. 剑指 Offer(C++版本)系列:剑指 Offer 10- II 青蛙跳台阶问题
  4. web onblur string
  5. 《雍正皇帝》文化专有词翻译策略的研究现状(Baker)
  6. arcgis server发布自定义打印模板及利用ArcGIS API javascript使用自定义打印服务打印地图
  7. MyEclipse8.5开发环境配置,SVN插件安装问题(转载)
  8. WordPress添加站点图标与底部备案信息
  9. python的for语句打印金字塔图形_python打印星号金字塔的方法
  10. Windows用户账户控制详解