我正在阅读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();
// [...]
}
[...]