netty4线程模型
netty4服务器端的启动是由ServerBootstrap引导的,启动代码如下
public class TimeServer {
public void bind(int port) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// 配置服务器的NIO线程租
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ChildChannelHandler());
// 绑定端口,同步等待成功
ChannelFuture f = b.bind(port).sync();
// 等待服务端监听端口关闭
f.channel().closeFuture().sync();
} finally {
// 优雅退出,释放线程池资源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
在创建服务端的时候实例化了2个EventLoopGroup,1个EventLoopGroup实际就是一个EventLoop线程组,负责管理EventLoop的申请和释放。两个EventloopGroup中,一个为BossGroup为Acceptor线程池;另一个为WokerGroup为IO线程池。服务器的启动是由类ServerBootstrap类引导的,先构建好启动前所需要的各个部件,然后bind()之后调用的顺序如下:
ServerBootstrap类的init()方法首先是给Channel设置options和attrs,然后把User提供的针对NioServerSocketChannel的Handler添加到Pipeline的末尾。接下来复制childOptions和childAttrs,最后实例化一个ChannelInitializer,添加到Pipeline的末尾。init()方法执行完毕之后,AbstractBootstrap的initAndRegister()方法会将NioServerSocketChannel注册到group里。注册前各个类的模型大致如下
在ServerBootstrap.init()的最后有以下代码:
而ChannelInitializer在channelRegistered事件触发后会调用initChannel()方法,随后把自己从Pipeline里删除,此时候EventLoopGroup,channel,handler类关系大致如下: