原文连接:http://xueliang.org/article/detail/20200712234015993promise
在Netty的线程模型中,对于一个TCP链接的读写操做,都是由一个单线程完成的,对于刚入门Netty的新手,这彻底颠覆咱们熟知的多线程可以加快处理速度,缩短处理时间的常规思路。
实际上,Netty采用了异步通讯模式,一个IO 线程能够并发处理N 个客户端链接和读写操做,这从根本上解决了传统同步阻塞IO 一链接一线程模型,架构的性能、弹性伸缩能力和可靠性都获得了极大的提高。多线程
将 Channel
注册到 Worker 线程组上架构
调用 NioEventLoopGroup
的 next()
从 Worker 线程组中获取一个 eventLoop
并发
根据线程组个数不一样,会调用 PowerOfTwoEventExecutorChooser
或者 GenericEventExecutorChooser
的 next()
方法,若是线程数是 2 的 N 次方,就选用 PowerOfTwoEventExecutorChooser
这个 EventLoop
选择类,使用位运算提升效率异步
调用选取的 eventLoop
的 register()
方法,能够看到,将 this
也就是当前 EventLoop
当作参数传入 promise.channel().unsafe().register()
方法oop
继续进到 promise.channel().unsafe().register
方法,到这里,终于将 eventLoop
赋值给了 Channel
,即 Channel
与 eventLoop
创建了绑定关系。性能
但Channel还未与线程绑定,继续往下看,当咱们平时在Handler里调用 ctx
(即 ChannelHandlerContext
类对象)的 write()
时,实际是获取 ctx
的 executor
执行写操纵事件,若未给 ctx
指定 executor
,则 ctx
会使用 对应的 channel
的 eventLoop
this
执行 eventLoop
的 execute()
方法spa
进到 execute()
方法内,先经过调用 inEventLoop()
方法,判断当前线程是不是 eventLoop
绑定的那个线程线程
若是不是,则可能 eventLoop
尚未绑定线程,则调用 startThread
方法建立一个线程
最终调用 eventLoop
的 doStartThread()
,由 executor
指定建立线程的任务。
到此,Channel - EventLoop - Thread 绑定在了一块儿,同时也能看出多个 Channel 可能绑定到 一个EventLoop上
Netty将一个TCP链接和一个固定的线程绑定,不须要进行线程切换以及线程同步,即节省资源又提升吞吐效率,除此以外咱们在阅读源码的过程当中,从EventLoop的选取,根据不一样的线程数,使用不一样的轮询器,能够看出Netty对于高性能的极致追求。