一道Netty面试题:boss线程池和worker线程池能不能合在一起?

Netty中Boss线程负责接收连接,Worker线程处理连接后的请求。通常Boss线程池与Worker线程池分开以降低复杂性和提高效率。面试题讨论了两者是否能合并,尽管Netty源码支持,但合并不常见,可能导致资源浪费和管理复杂性增加。了解Netty的线程模型和构造器用法对于优化服务器性能至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

这篇帖子我估计要反复修改,我不确定面试官是不是随口问的(就是可能他自己也没仔细想过这个问题。。。),我当时回答的是不能,我确实不大明白为啥要合在一起,合在一起你也是要有线程去处理连接,一部分线程去处理请求。而且放在一起不是增加复杂度(耦合)了吗?面试的时候思路容易不清晰,其实这段还是看过的,而且之前的帖子里还写过,netty源码默认就是支持的,只不过平时使用的都是主从多线程reactor。

相关知识点

Netty中的三种线程模型?

单线程Reactor、多线程Reactor、主从多线程Reactor(前面已经介绍过了)。

boss线程和worker线程 ?

Boss线程:每个server服务器都会有一个boss线程,每绑定一个InetSocketAddress都会产生一个boss线程,比如:我们开启了两个服务器端口80和443,则我们会有两个boss线程。一个boss线程在端口绑定后,会接收传进来的连接,一旦连接接收成功,boss线程会指派一个worker线程处理连接。

Worker线程:一个NioServerSocketChannelFactory会有一个或者多个worker线程。一个worker线程在非阻塞模式下为一个或多个Channels提供非阻塞读或写。

偷张图:

                                

Group构造器

平时都是这么用的(主从多线程):

 EventLoopGroup bossGroup = new NioEventLoopGroup();

        EventLoopGroup group = new NioEventLoopGroup();
        try {
            ServerBootstrap sb = new ServerBootstrap();
            sb.option(ChannelOption.SO_BACKLOG, 1024);
            sb.group(group, bossGroup) // 绑定线程池
                    .channel(NioServerSocketChannel.class) // 指定使用的channel
                    .localAddress(this.port)// 绑定监听端口
                     ...略

跟一下源码:


    /**
     * Specify the {@link EventLoopGroup} which is used for the parent (acceptor) and the child (client).
     */
    @Override
    public ServerBootstrap group(EventLoopGroup group) {
        return group(group, group);
    }

    /**
     * Set the {@link EventLoopGroup} for the parent (acceptor) and the child (client). These
     * {@link EventLoopGroup}'s are used to handle all the events and IO for {@link ServerChannel} and
     * {@link Channel}'s.
     */
    public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        super.group(parentGroup);
        if (childGroup == null) {
            throw new NullPointerException("childGroup");
        }
        if (this.childGroup != null) {
            throw new IllegalStateException("childGroup set already");
        }
        this.childGroup = childGroup;
        return this;
    }

这里提供了两个构造器,单参数即为连接与请求处理线程公用的线程池( which is used for the parent (acceptor) and the child (client).),当 EventLoopGroup bossGroup = new NioEventLoopGroup()不填值时,默认为cpu核数*2,EventLoopGroup bossGroup = new NioEventLoopGroup(1)则为单线程reactor模型;当调用的构造器为两个参数时,则是常用的多线程模型,通常也有这种写法:

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)

这里就是boss线程池大小为1,worker线程池大小为cpu核数*2,这里就有一个问题,boss thread只有一个, 但是为什么要用thread pool? 原因如下:
1.可能有多个channel factory, 这些factory可以共用一个boss thread pool来创建boss thread.。
2.boss thread可以中途进行释放, 为了避免重复create的开销, 可以用一个小型的thread pool来管理 。

总结

多看源码,温故知新!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值