Netty源码解析(六)Channel的register操作
本文最后更新于:April 11, 2022 pm
Netty 源码分析系列:
Netty 源码解析(一): 开始
Netty 源码解析(二): Netty 的 Channel
Netty 源码解析(三): Netty 的 Future 和 Promise
Netty 源码解析(四): Netty 的 ChannelPipeline
Netty 源码解析(五): Netty 的线程池分析
Netty 源码解析(六): Channel 的 register 操作
Netty 源码解析(七): NioEventLoop 工作流程
Netty 源码解析(八): 回到 Channel 的 register 操作
Netty 源码解析(九): connect 过程和 bind 过程分析
目录
Channel 的 register 操作
经过前面的铺垫,我们已经具备一定的基础了,我们开始来把前面学到的内容揉在一起。这节,我们会介绍 register 操作,这一步其实是非常关键的,对于我们源码分析非常重要。
我们从 EchoClient 中的 connect() 方法出发,或者 EchoServer 的 bind(port) 方法出发,都会走到 initAndRegister() 这个方法:
1 |
|
initAndRegister() 这个方法我们已经接触过两次了,前面介绍了 1️⃣ Channel 的实例化,实例化过程中,会执行 Channel 内部 Unsafe 和 Pipeline 的实例化,以及在上面 2️⃣ init(channel) 方法中,会往 pipeline 中添加 handler(pipeline 此时是 head+channelnitializer+tail)。
我们这节终于要揭秘 ChannelInitializer 中的 initChannel 方法了~~~
现在,我们继续往下走,看看 3️⃣ register 这一步:
1 |
|
我们说了,register 这一步是非常关键的,它发生在 channel 实例化以后,大家回忆一下当前 channel 中的一些情况:
实例化了 JDK 底层的 Channel,设置了非阻塞,实例化了 Unsafe,实例化了 Pipeline,同时往 pipeline 中添加了 head、tail 以及一个 ChannelInitializer 实例。
上面的 config().group()
方法会返回前面实例化的 NioEventLoopGroup 的实例,然后调用其 register(channel) 方法:
// MultithreadEventLoopGroup
1 |
|
next() 方法很简单,就是选择线程池中的一个线程(还记得 chooserFactory 吗),也就是选择一个 NioEventLoop 实例,这个时候我们就进入到 NioEventLoop 了。
NioEventLoop 的 register(channel) 方法实现在它的父类 SingleThreadEventLoop 中:
1 |
|
上面的代码实例化了一个 Promise,将当前 channel 带了进去:
1 |
|
拿到 channel 中关联的 Unsafe 实例,然后调用它的 register 方法:
我们说过,Unsafe 专门用来封装底层实现,当然这里也没那么“底层”
// AbstractChannel#AbstractUnsafe
1 |
|
到这里,我们要明白,NioEventLoop 中是还没有实例化 Thread 实例的。
这几步涉及到了好几个类:NioEventLoop、Promise、Channel、Unsafe 等,大家要仔细理清楚它们的关系。
对于我们前面过来的 register 操作,其实提交到 eventLoop 以后,就直接返回 promise 实例了,剩下的register0 是异步操作,它由 NioEventLoop 实例来完成。
我们这边先不继续往里分析 register0(promise) 方法,先把前面欠下的 NioEventLoop 中的线程介绍清楚,然后再回来介绍这个 register0 方法。
Channel 实例一旦 register 到了 NioEventLoopGroup 实例中的某个 NioEventLoop 实例,那么后续该 Channel 的所有操作,都是由该 NioEventLoop 实例来完成的。
这个也非常简单,因为 Selector 实例是在 NioEventLoop 实例中的,Channel 实例一旦注册到某个 Selector 实例中,当然也只能在这个实例中处理 NIO 事件。
本文作者: 墨水记忆
本文链接: https://tothefor.com/DragonOne/4044829207.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!