通过之前关于Netty的分析,我们已经了解到,一般我们在Netty服务端启动的时候会传入boss线程组和worker线程组,这节结合之前我们的分析,来聊聊Netty中的线程处理。
我们知道,Netty是一个高性能的网络框架,针对网络中,我们一般常见处理是网络的连接的建立、消息读写等。这些在Netty中线程模型是怎样的。
首先说一下一个结论,在Netty中每个Channel都会在全局运行的时候绑定到一个线程中去,不管是ServerChannel还是ClientChannel。
首先一般的Netty服务端启动程序如下:
public static void main(String[] args) {
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boss, worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("hello world hanlder", new HelloWorldHandler());
}
});
try {
ChannelFuture channelFuture = bootstrap.bind(8080).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
或者也可以这样:
public static void main(String[] args) {
EventLoopGroup worker = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("hello world hanlder", new HelloWorldHandler());
}
});
try {
ChannelFuture channelFuture = bootstrap.bind(8080).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
这里需要强调的一点是,第一种方式中,boss线程组如果没有绑定多个端口的情况下,建议手动指定线程个数为1,因为如果不指定线程数的话,Netty中默认线程组中线程的数量是CPU*2,而Netty中对于Server的Channel来说,是根据端口号来绑定线程的,当然了,这样指定也是可以的,只不过,只有一个线程会运行,其他的线程只是创建了,并未运行。
在Netty中我们常用的线程组就是NioEventLoopGroup,而其中的线程为NioEventLoop,二者的类继承结构如下:


这里说下,上面这两段代码的区别,第一种就是我们常见的,一个worker线程,一个boss线程,第二种,其实也很好理解,我们看下其方法实现就全明白了:
super.group(parentGroup);
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
this.childGroup = ObjectUtil.checkNotNull(childGroup, "childGroup");
return this;
}
public ServerBootstrap group(EventLoopGroup group) {
return group(group, group);
}
其实说白了,第二种方式就是worker线程组既充当了boss线程组又充当了woker线程组,仅此而已,没有什么特别的,因为Netty中是每个Channel绑定到一个线程上去的,和具体的线程池关系不大。
首先我们看下NioEventLoopGroup是怎么进行初始化的,在父类MultithreadEventExecutorGroup中,进行了如下处理:
protected MultithreadEventExecutorGroup(

本文详细剖析了Netty中的线程处理机制,包括EventLoopGroup(boss和worker)的使用,Channel如何绑定到特定线程,以及NioEventLoopGroup的初始化和工作原理。重点讲解了NioEventLoop的执行逻辑和Channel与NioEventLoop的绑定过程。
最低0.47元/天 解锁文章
5554

被折叠的 条评论
为什么被折叠?



