java - 在什么情况下 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
?
解决方案
这种代码确保只有正确的 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(); // [...] } [...]
推荐阅读
- c++ - 递归代码以退出代码 3221225477 退出
- sql - 如何解决错误“无法对包含聚合或子查询的表达式执行聚合函数”
- python - 数据库中缺少字段但存在于 Django 的模型中
- javascript - 如何将 SharePoint 列表中的值显示到网页
- javascript - 为什么在尝试将日期时间类型转换为日期时出现错误“未定义时刻”?
- python - 如何从当前项目向 scrapyd 添加新服务
- wso2 - WSO2 自定义中介设置信封的值
- shadow-dom - 当阴影设置为 true 时,如何仅在 stencilJS 中获取被点击的元素
- android - 应用程序在 java.net.SocketTimeoutException 上崩溃:超时(Kotlin、Retrofit)
- python - 由于 wx 问题,无法使用 view_cube 命令