首页 > 解决方案 > 在什么情况下 eventloop.inEventLoop() == false?

问题描述

我正在阅读 netty 4 源代码。eventLoop.inEventLoop()到处出现。根据 Netty 在行动:

一个 Channel 在其生命周期中注册一个 EventLoop。可以将单个 EventLoop 分配给一个或多个 Channel。一个通道有并且只有一个事件循环/线程。

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

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

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

标签: javanettyniochannel

解决方案


这种代码确保只有正确的 eventLoop/thread 才能处理/更改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();
            // [...]
        }
    [...]

推荐阅读