我正在阅读netty 4源代码。 eventLoop.inEventLoop()随处出现。
根据Netty in Action:


一个通道在其生命周期内通过一个EventLoop注册。
单个EventLoop可以分配给一个或多个通道。
一个通道只有一个eventLoop / thread。


从理论上讲,eventLoop.inEventLoop()是为了确保代码块由分配的eventLoop / thread执行。此外,如果您从非io线程调用某些内容,则eventLoop.inEventLoop()变为false,并将由分配的eventLoop / thread执行。

例如,以下代码转到未注册通道(分配给事件循环/线程)的else块(NioSocketChannel$NioSocketChannelUnsafe(AbstractChannel$AbstractUnsafe).register(EventLoop, ChannelPromise))。

if (eventLoop.inEventLoop()) {
    register0(promise);
} else {
    try {
        eventLoop.execute(new Runnable() {
            @Override
            public void run() {
                register0(promise);
            }
        });
    } catch (Throwable t) {
...
    }
}


我真的很困惑,eventLoop.inEventLoop()的意义是什么。
eventLoop.inEventLoop()保护什么?

除了上述以外,您能否在实践中给我一些更具体的例子来说明为什么以及如何eventloop.inEventLoop() == false?你叫什么样的代码?你叫哪里代码如何生成eventloop.inEventLoop() == false

最佳答案

这种代码可确保只有正确的eventLoop / thread才能与/ cc Channel对象一起使用/更改。当只有一个特定的线程可以与Channel对象一起工作时,这解决了许多竞争条件和多线程问题。这与所谓的“线程安全”有关,是否将某个类视为“线程安全”也与否有关。该代码可以阅读如下:

if (amIOnTheCorrectThread()) {
    doTheActualWork(); // I do the work
} else {
   scheduleOnTheCorrectThread.performAction({ doTheActualWork(); }); // let him do the work
}


根据您是否在正确的线程上,直接在正确的线程上完成工作,或者将任务卸载到正确的线程上,以便其他线程执行工作。另一个线程通过无限循环来执行此操作,并检查是否有任何新任务要执行。例如,检查run()类的io.netty.channel.ThreadPerChannelEventLoop方法:


@Override
protected void run() {
    for (;;) {
        Runnable task = takeTask();
        if (task != null) {
            task.run();
            // [...]
        }
    [...]

08-04 02:28