netty如此强大和优秀的通信框架,是如何封装和使用线程池的。
其实这一点我是非常的好奇,我们在使用netty的时候,似乎没有感受到哪里有线程池相关的操作。
这篇文章解密 netty使用线程池的精妙绝伦的地方。
netty中和线程池相关的东西我截取了一份netty服务端的代码,如下:
上图中的EventLoopGroup 实际上就是线程池,只不过netty是基于事件驱动的,它想要把一切都描述的和事件相关,所以它给线程池套上了一个事件马甲,然后叫做 “事件循环组”。
证据如下:我们点进去 NioEventLoopGroup,可以看到,它继承自 MultithreadEventLoopGroup ,从名字就可以看出来,多线程事件循环组。
如果我们不填写线程的个数,它默认是0,然后我们再点进去 MultithreadEventLoopGroup
可以看到下图点进去的内容:静态代码块初始化了线程的个数,这回是根据当前环境下的内核的个数 * 2 来当做最大线程数的。
接着再看下边,这依旧是MultithreadEventLoopGroup点进来看到的:实际上如果你制定了线程数,那么就用你的线程数,如果没有指定,则使用默认的,也就是 内核数*2 。
如下图:红色的实际上就是 EventLoop,这是实际上就是绑定一个线程。 而EventLoopGroup实际上是实现了 EventExecutorGroup,它是具有绿色框的功能,包括了任务调度。
EventLoopGroup ——> 线程池
EventLoop ——> 提前创建出来的工作线程
channel ——> 任务执行单元,相当于是继承了 Thread类,或者实现了 Runnable接口的类
也是netty的设计上的一个需求吧,它期望进来的一个任务,一旦被分配到某个 EventLoop上,那么此后都被它执行。也就是 EventLoop 和 channel 是一个强绑定的关系。
另外EventLoop也是维护了一个任务队列。上边的需求,实际上避免了线程与线程之间的数据同步。