原文链接http://xueliang.org/article/detail/20200712234015993

前言

在Netty的线程模型中,对于一个TCP连接的读写操作,都是由一个单线程完成的,对于刚入门Netty的新手,这完全颠覆我们熟知的多线程能够加快处理速度,缩短处理时间的常规思路。

实际上,Netty采用了异步通信模式,一个IO 线程可以并发处理N 个客户端连接和读写操作,这从根本上解决了传统同步阻塞IO 一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。

源码阅读

Channel 注册到 Worker 线程组上

调用 NioEventLoopGroupnext() 从 Worker 线程组中获取一个 eventLoop

根据线程组个数不同,会调用 PowerOfTwoEventExecutorChooser 或者 GenericEventExecutorChoosernext() 方法,如果线程数是 2 的 N 次方,就选用 PowerOfTwoEventExecutorChooser 这个 EventLoop 选择类,使用位运算提高效率

调用选取的 eventLoopregister() 方法,可以看到,将 this 也就是当前 EventLoop 当做参数传入 promise.channel().unsafe().register() 方法

继续进到 promise.channel().unsafe().register 方法,到这里,终于将 eventLoop 赋值给了 Channel,即 ChanneleventLoop 建立了绑定关系。

但Channel还未与线程绑定,继续往下看,当我们平时在Handler里调用 ctx (即 ChannelHandlerContext 类对象)的 write() 时,实际是获取 ctxexecutor 执行写操纵事件,若未给 ctx 指定 executor,则 ctx 会使用 对应的 channeleventLoop

执行 eventLoopexecute() 方法

进到 execute() 方法内,先通过调用 inEventLoop() 方法,判断当前线程是否是 eventLoop 绑定的那个线程

如果不是,则可能 eventLoop 还没有绑定线程,则调用 startThread 方法创建一个线程

最终调用 eventLoopdoStartThread() ,由 executor 指定创建线程的任务。

到此,Channel - EventLoop - Thread 绑定在了一起,同时也能看出多个 Channel 可能绑定到 一个EventLoop上

总结

Netty将一个TCP连接和一个固定的线程绑定,不需要进行线程切换以及线程同步,即节省资源又提高吞吐效率,除此之外我们在阅读源码的过程中,从EventLoop的选取,根据不同的线程数,使用不同的轮询器,可以看出Netty对于高性能的极致追求。

原文链接http://xueliang.org/article/detail/20200712234015993

Netty源码阅读之如何将TCP的读写操作和指定线程绑定的更多相关文章

  1. Netty源码阅读(一) ServerBootstrap启动

    Netty源码阅读(一) ServerBootstrap启动 转自我的Github Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速 ...

  2. Netty 源码解析(六): Channel 的 register 操作

    原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 今天是猿灯塔“365篇原创计划”第六篇. 接下来的时间灯塔君持续更新Netty系列一共九篇   Netty 源码解析(一 ):开始 Netty ...

  3. netty源码阅读之UnpooledByteBufAllocator

    使用IDEA阅读源码Navigate下面的工具是个好东西 .可以帮助分析类的结构等 ByteBufAllocator主要用来生成三种ByteBuf :HeadBuffer,DirectBuffer,C ...

  4. Netty 源码阅读的思考------耗时业务到底该如何处理

    目录大纲: 前言 处理耗时业务的第一种方式-------handler 种加入线程池 处理耗时业务的第二种方式-------Context 中添加线程池 总结:两种方式的对比和思考 前言 熟悉 Net ...

  5. Netty 源码解析(九): connect 过程和 bind 过程分析

    原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 今天是猿灯塔“365篇原创计划”第九篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源 ...

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

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

  7. Netty 源码解析(八): 回到 Channel 的 register 操作

    原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 今天是猿灯塔“365篇原创计划”第八篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源 ...

  8. Netty 源码解析(七): NioEventLoop 工作流程

    原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 今天是猿灯塔“365篇原创计划”第七篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源 ...

  9. Netty 源码解析(五): Netty 的线程池分析

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

随机推荐

  1. 囚徒问题(100 prisoners problem)的python验证

    密码学课上老师介绍了这样一个问题,囚徒问题(100 prisoners problem):一百个囚徒被关在牢房里,典狱长给他们最后一次机会,100人依次进入一个有100个抽屉的牢房,每个抽屉置乱放入1 ...

  2. 《Java并发编程的艺术》第4章 Java并发编程基础 ——学习笔记

    参考https://www.cnblogs.com/lilinzhiyu/p/8086235.html 4.1 线程简介 进程:操作系统在运行一个程序时,会为其创建一个进程. 线程:是进程的一个执行单 ...

  3. rust 神奇的特质

    pub trait Summary { fn summarize_author(&self) -> String; fn summarize(&self) -> Strin ...

  4. ida 调试android之路

    系统: Mac OSX 调试环境:IDA7.0,  adb 手机环境:红米手机 android 4.4.4 前提条件: 红米手机root之路:https://www.cnblogs.com/dzqdz ...

  5. 关于margin外边距合并的问题

    一 .兄弟元素margin外边距合并演示   当两个垂直方向相邻的兄弟元素都为常规流块盒,他们之间垂直方向的外边距不是两者之和,而是取两者中的最大值.这种现象被称为相邻的兄弟元素垂直方向外边距合并. ...

  6. 11、vue-路由

    1.路由: 官方提供一个插件,构建单页面应用,主要实现得功能页面得切换.组件得跳转 2.vue中得路由:vue-router包,如果是脚手架进行搭建得,那么是不需要安装vue-router这个包得,因 ...

  7. PHP丨PHP基础知识之流程控制for循环「理论篇」

    今天公司同事在看for循环,那么我们今天就来讲讲for循环吧! for循环是编程语言中一种循环语句,而循环语句由循环体及循环的判定条件两部分组成,其表达式为:for(单次表达式;条件表达式;末尾循环体 ...

  8. 谷歌Chrome成最受欢迎的浏览器 它为啥好用?

    毫无疑问,在搜索引擎领域,谷歌是绝对的主导者.但是,一般人却很容易低估我们受到的“控制”.比如,它的浏览器Chrome. 在不到九年的时间,谷歌Chrome浏览器已经成为全球使用最多的网页浏览器.目前 ...

  9. TCP实战一(三握四挥、流量控制)

    上一篇博文已经介绍了tcpdump的一些基本操作与命令,今天这篇博文将带你解密如何利用wireshark对tcpdump抓到的数据包进行可视化分析! 参考文献:https://zhuanlan.zhi ...

  10. synchronized与锁升级

    1 为什么需要synchronized? 当一个共享资源有可能被多个线程同时访问并修改的时候,需要用锁来保证数据的正确性.请看下图: 线程A和线程B分别往同一个银行账户里面添加货币,A线程从内存中读取 ...