源码解析-Netty源码之EventLoopGroup
作者:互联网
从Netty官方给出的example包着手点分析,echo 回声,也就是客户端传什么,服务端传回什么
先从客户端开始看
属性,ip地址,端口号,数据大小之类的 四个写死了的
判断ssl是否为空,来决定是否需要初始化SslContext (可以理解为一些客户端的初始化配置,我们的例子中默认是null)
下面重点来了,前面暂时都可以忽略
核心点几步:
1. 创建一个线程池组group;
2. 创建一个客户端Bootstrap;
3. 加入线程池组,
4. 加入socketChannel, //设置了channelFactory 用来创建NioSocketChannel
5. 定义了ChannelInitializer,加入了自定义的handel;
6. 异步connect; //这一步做的事比较多,new一个channel,初始化一个pipeline,将hendel全部加入到pipeline。从group中拿一个loop 将channel注入到loop中,启动loop线程,将channel注册到selector上
7. 关闭channel;
8. 关闭线程池组group;
这一篇重点分析第一步 创建线程池组group 与线程loop
注意 这里的group与loop的概念区别于jdk的线程池与线程,更像是一种公司与打工人的关系,公司负责提供打工人,打工人负责具体做事情。
loop打工人用来处理连接的生命周期中所发生的事件,在内部,将会为每个Channel分配一个loop。
group 是一个loop 池,包含很多的loop,需要接活的时候直接让公司派出一个打工人来干活
Netty 为每个 Channel 分配了一个 loop,用于处理用户连接请求、对用户请求的处理等所有事件。
一个 Channel 一旦与一个 loop 相绑定,那么在 Channel 的整个生命周期内是不能改变的。一个 loop 可以与多个 Channel 绑定。即 Channel 与 EventLoop 的关系是 n:1的关系
---
继承结构
前面所说的loop和group 落地的实现就是NioEventLoop和NioEventLoopGroup
从继承关系可以看出,无论是loop还是group都继承自 jdk的Executor,都具有最原始的execute()方法
最顶层Executor,然后是线程池,然后时可以定时处理的线程池
loop继承了SingleThreadEventLoop,看名字 这是个单线程的线程池,也就是说 loop内部其实放着一个只有一个线程的线程池,具体干活就靠着一个线程了
group继承子MultithreadEventLoopGroup.多种线程事件的线程池,与其说是线程池,不如说这是一个loop池,存放了各种各样的loop,还具有一些找哪个loop出来干活的方法
源码分析
从这里为入口开始探索
先给个线程数为0,继续
先给个executor为null,继续
先给个默认的selectorProvider,用来创建selector监听端口号,这个provider方法由jdk1.4提供
给个默认的选择策略
给个默认的拒绝策略 (直接抛异常)
到了父类的构造器了,线程数如果是0,直接给个默认大小 (cpu核心数*2) 这里的args参数就是什么选择策略啊 拒绝策略啊 不是本篇重点,继续往下走
初始化了个DefaultEventExecutorChooserFactory,这东西就是用来选择loop的,也就是有需求的时候 他会从从group里选出一个loop 交给channel
来到重点了,重要的初始化过程都在这进行 这一个方法被我拆成了几个部分分别介绍
首先判断一下线程数,也是loop数,刚才给了 cpu核心数*2
判断executor是否为null,如果为null创建一个,刚才一直没给,会在这里new一个
executor是什么呢
未完待续...
标签:Netty,group,channel,一个,源码,线程,Channel,EventLoopGroup,loop 来源: https://www.cnblogs.com/ttaall/p/14201190.html