为什么每个线程都需要在netty中执行selector.select

ujv3wf0j  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(360)

当我阅读netty-4.0.0.final.jar的源代码时,我在nioeventloop.java中发现了以下令人费解的代码:

protected void run() {
    for (;;) {
        oldWakenUp = wakenUp.getAndSet(false);
        try {
            if (hasTasks()) {
                selectNow();
            } else {
                select();
                if (wakenUp.get()) {
                    selector.wakeup();
                }
            }
            //ignore some code
            processSelectedKeysPlain(selector.selectedKeys());
            //ignore some code
    }
}

在传统的网络程序中,使用一个专用线程来接收就绪事件(接受连接、读取、写入),并使用一个线程池来提供服务。
我明白了。
内蒂也遵循这种模式。使用

ServerBootstrap.group(EventLoopGroup parentGroup, EventLoopGroup childGroup)

不是

ServerBootstrap.group(EventLoopGroup group)

谢谢回复!

vybvopom

vybvopom1#

在传统的网络程序中,使用一个专用线程来接受连接,使用一个线程池来提供服务。
这是因为accept连接部分是阻塞的,它需要在一个线程中完成,以便可以与服务器建立连接,并且必须将连接处理(读、写)委派给不同的线程以保持运行。
为什么netty选择在每个线程中混合接受和提供服务的任务?
这是因为它使用 selectjava.nio (非阻塞i/o)包。select从c/c++开始就存在了,它允许同步i/o多路复用。简而言之,它允许监视多个套接字,并检查这些套接字是否正在读取、写入或有异常。
因为 select 的非阻塞特性它可以用来检查连接以及在单个线程中处理这些连接。

相关问题