Netty中NioEventLoop源码解析

【Unity实战篇 】| Unity实现 文本框可以自适应大小,到达最大宽度之后再缩小字体 Unity实现 Text文本框可以自适应大小,到达最大宽度之后再缩小字体 需求:在文本框可以自适应大小拉伸的前提下,增加一个最大限制宽度,使其到达最大宽度后 再启用 Best Fit 实现自适应改变文字大小以适应文本框的大小。 在Unity中经常会用到文本组件的自适应大小功能,一般使用HorizontalLayoutGroup和ContentSizeFitter组件配合即可实现文本自适应的效果。 阅读详情

1. 字段解析

NioEventLoop 类是 Netty 4.1 中实现 Reactor 模型的单线程事件循环类,继承自 SingleThreadEventLoop,负责处理 I/O 事件、任务调度和事件分发。以下是类中定义的所有字段,逐一解析其作用和实现细节。

1.1 CLEANUP_INTERVAL

定义:

private static final int CLEANUP_INTERVAL = 256; // XXX Hard-coded value, but won't need customization.
  • 初始化:硬编码为 256。

  • 作用:

    • 定义清理已取消 SelectionKey 的间隔。
    • 在 cancel(SelectionKey) 方法中,当 cancelledKeys 达到 256 时,设置 needsToSelectAgain = true,触发 selectAgain() 清理 Selector。
  • 使用场景:

    • 在 cancel(SelectionKey) 方法中:
      cancelledKeys++;
      if (cancelledKeys >= CLEANUP_INTERVAL) {
          cancelledKeys = 0;
          needsToSelectAgain = true;
      }
      
    • 防止频繁调用 selectAgain(),优化性能。
  • 设计理念:

    • 硬编码 256 是一个经验值,平衡清理频率和性能开销。
    • 避免每次取消 SelectionKey 都调用 selectAgain(),减少系统调用开销。

1.2 DISABLE_KEY_SET_OPTIMIZATION

定义:

private static final boolean DISABLE_KEY_SET_OPTIMIZATION =
        SystemPropertyUtil.getBoolean("io.netty.noKeySetOptimization", false);
  • 类型:boolean,静态常量。

  • 修饰符:private static final,不可修改。

  • 初始化:通过 SystemPropertyUtil.getBoolean("io.netty.noKeySetOptimization", false) 读取系统属性,默认为 false。

  • 作用:

    • 控制是否禁用 SelectedSelectionKeySet 优化。
    • 若为 true,openSelector() 不替换 Selector 的默认 selectedKeys 集合,直接使用 HashSet。
  • 使用场景:

    • 在 openSelector() 方法中:
      if (DISABLE_KEY_SET_OPTIMIZATION) {
          return new SelectorTuple(unwrappedSelector);
      }
      
    • 若优化启用(false),使用 SelectedSelectionKeySet(基于数组)替换默认 HashSet,提升 SelectionKey 处理效率。
  • 设计理念:

    • 提供配置选项,允许用户在调试或兼容性问题时禁用优化。
    • 默认启用优化,适用于高性能场景。

1.3 MIN_PREMATURE_SELECTOR_RETURNS

定义:

private static final int MIN_PREMATURE_SELECTOR_RETURNS = 3;
  • 初始化:硬编码为 3。
  • 作用:
    • 定义 Selector.select() 连续过早返回的最小次数阈值,用于检测空轮询问题。
    • 在 selectReturnPrematurely 方法中,若 selectCnt > MIN_PREMATURE_SELECTOR_RETURNS,记录调试日志。
  • 使用场景:
    • 在 selectReturnPrematurely 方法中:
      if (selectCnt > MIN_PREMATURE_SELECTOR_RETURNS && logger.isDebugEnabled()) {
          logger.debug("Selector.select() returned prematurely {} times in a row for Selector {}.", selectCnt - 1, selector);
      }
      
  • 设计理念:
    • 设置 3 次作为合理阈值,避免误判正常返回。
    • 与 SELECTOR_AUTO_REBUILD_THRESHOLD 配合,检测严重空轮询问题。

1.4 SELECTOR_AUTO_REBUILD_THRESHOLD

定义:

private static final int SELECTOR_AUTO_REBUILD_THRESHOLD;
static {
    int selectorAutoRebuildThreshold = SystemPropertyUtil.getInt("io.netty.selectorAutoRebuildThreshold", 512);
    if (selectorAutoRebuildThreshold < MIN_PREMATURE_SELECTOR_RETURNS) {
        selectorAutoRebuildThreshold = 0;
    }
    SELECTOR_AUTO_REBUILD_THRESHOLD = selectorAutoRebuildThreshold;
}
  • 初始化:
    • 通过 SystemPropertyUtil.getInt("io.netty.selectorAutoRebuildThreshold", 512) 读取系统属性,默认 512。
    • 若值小于 MIN_PREMATURE_SELECTOR_RETURNS(3),设为 0(禁用重建)。
  • 作用:
    • 定义 Selector 连续过早返回的阈值,若 selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD,触发 rebuildSelector() 重建 Selector。
    • 解决 Java NIO 的空轮询 bug(如 https://github.com/netty/netty/issues/2426)。
  • 使用场景:
    • 在 unexpectedSelectorWakeup 方法中:
      if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 && selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {
          logger.warn("Selector.select() returned prematurely {} times in a row; rebuilding Selector {}.", selectCnt, selector);
          rebuildSelector();
          return true;
      }
      
  • 设计理念:
    • 默认 512 次是一个经验值,平衡性能和稳定性。
    • 提供系统属性配置,允许用户调整或禁用(设为 0)。

1.5 selectNowSupplier

定义:

private final IntSupplier selectNowSupplier = new IntSupplier() {
    @Override
    public int get() throws Exception {
        return selectNow();
    }
};
  • 作用:
    • 提供 selector.selectNow() 的封装,供 selectStrategy.calculateStrategy 使用。
    • 返回就绪的 SelectionKey 数量,决定是否执行非阻塞 select。
  • 使用场景:
    • 在 run() 方法中:
      strategy = selectStrategy.calculateStrategy(selectNowSupplier, hasTasks());
      
    • 若 hasTasks() 为 true,selectNowSupplier.get() 调用 selectNow() 检查是否有立即就绪的 I/O 事件。
  • 设计理念:
    • 抽象 selectNow() 调用,便于 SelectStrategy 扩展。
    • 异常由 run() 方法捕获,增强鲁棒性。

1.6 selector

定义:

private Selector selector;
  • 初始化:
    • 在构造函数中通过 openSelector() 初始化:
      final SelectorTuple selectorTuple = openSelector();
      this.selector = selectorTuple.selector;
      
    • 若启用 SelectedSelectionKeySet,selector 是 SelectedSelectionKeySetSelector(包装类);否则是原生 Selector。
  • 作用:
    • Java NIO 的核心组件,管理 Channel 的 I/O 事件(如 OP_READ、OP_WRITE)。
    • 用于 select()、selectNow() 等操作,监控就绪事件。
  • 使用场景:
    • run() 方法调用 select(curDeadlineNanos) 和 processSelectedKeys()。
    • wakeup() 方法调用 selector.wakeup()。
    • rebuildSelector0() 迁移 Channel 到新 Selector。
  • 设计理念:
    • 封装 NIO 的 Selector,支持优化(如 SelectedSelectionKeySet)。

1.7 unwrappedSelector

定义:

private Selector unwrappedSelector;
  • 初始化:
    • 在 openSelector() 中通过 provider.openSelector() 创建:
      unwrappedSelector = provider.openSelector();
      this.unwrappedSelector = selectorTuple.unwrappedSelector;
      
  • 作用:
    • 存储原生 NIO Selector,不受 SelectedSelectionKeySet 包装。
    • 用于直接注册 Channel 或在优化失败时回退。
  • 使用场景:
    • register0() 方法注册 Channel:
      ch.register(unwrappedSelector, interestOps, task);
      
    • rebuildSelector0() 迁移 Channel 到新 Selector。
  • 设计理念:
    • 分离原生和包装 Selector,提高兼容性和灵活性。

1.8 selectedKeys

定义:

private SelectedSelectionKeySet selectedKeys;
  • 初始化:
    • 在 openSelector() 中:
      final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
      selectedKeys = selectedKeySet;
      
    • 若优化失败或 DISABLE_KEY_SET_OPTIMIZATION 为 true,设为 null。
  • 作用:
    • 存储就绪的 SelectionKey,使用数组结构替换默认 HashSet。
    • 提高处理性能,减少内存分配和迭代开销。
  • 使用场景:
    • 在 processSelectedKeys() 方法中:
      if (selectedKeys != null) {
          processSelectedKeysOptimized();
      } else {
          processSelectedKeysPlain(selector.selectedKeys());
      }
      
    • processSelectedKeysOptimized() 迭代 selectedKeys.keys 数组。
  • 设计理念:
    • 优化 SelectionKey 处理,适合高吞吐场景。
    • 可通过 DISABLE_KEY_SET_OPTIMIZATION 禁用,增强兼容性。

1.9 provider

定义:

private final SelectorProvider provider;
  • 初始化:
    • 通过构造函数传入并检查非空:
      this.provider = ObjectUtil.checkNotNull(selectorProvider, "selectorProvider");
      
    • 通常为 SelectorProvider.provider()(默认 NIO 提供者)。
  • 作用:
    • 用于创建 Selector 和 Channel 实例,支持 NIO 操作。
  • 使用场景:
    • 在 openSelector() 中:
      unwrappedSelector = provider.openSelector();
      
  • 设计理念:
    • 抽象 NIO 提供者,允许自定义实现(实际很少使用)。

1.10 AWAKE

定义:

private static final long AWAKE = -1L;
  • 初始化:硬编码为 -1L。

  • 作用:

    • 表示 nextWakeupNanos 的状态,事件循环已唤醒(不阻塞在 select 中)。
  • 使用场景:

    • 在 nextWakeupNanos 更新中:
      nextWakeupNanos.lazySet(AWAKE);
      
    • 在 wakeup() 方法中:
      nextWakeupNanos.getAndSet(AWAKE) != AWAKE
      
  • 设计理念:

    • 简单常量,表示非阻塞状态。

1.11 NONE

定义:

private static final long NONE = Long.MAX_VALUE;
  • 初始化:硬编码为 Long.MAX_VALUE。
  • 作用:
    • 表示 nextWakeupNanos 的状态,无定时任务,Selector 可无限期阻塞。
  • 使用场景:
    • 在 run() 方法中:
      if (curDeadlineNanos == -1L) {
          curDeadlineNanos = NONE;
      }
      
    • 在 select() 方法中:
      if (deadlineNanos == NONE) {
          return selector.select();
      }
      
  • 设计理念:
    • 确保无任务时 Selector 无限期阻塞,节省 CPU。

1.12 nextWakeupNanos

定义:

private final AtomicLong nextWakeupNanos = new AtomicLong(AWAKE);
  • 初始化:设为 AWAKE(-1L)。
  • 作用:
    • 存储 Selector 的下一次唤醒时间(纳秒):
      • AWAKE (-1L):事件循环已唤醒。
      • NONE (Long.MAX_VALUE):无定时任务。
      • 其他值:最早定时任务的截止时间。
    • 通过 AtomicLong 确保线程安全,支持外部线程唤醒。
  • 使用场景:
    • 在 run() 方法中:
      nextWakeupNanos.set(curDeadlineNanos);
      nextWakeupNanos.lazySet(AWAKE);
      
    • 在 wakeup() 方法中:
      if (!inEventLoop && nextWakeupNanos.getAndSet(AWAKE) != AWAKE) {
          selector.wakeup();
      }
      
    • 在 beforeScheduledTaskSubmitted 和 afterScheduledTaskSubmitted 中:
      return deadlineNanos < nextWakeupNanos.get();
      
  • 设计理念:
    • 替代 wakenUp(此版本缺失)控制唤醒。
    • 使用 lazySet 优化性能,减少内存屏障开销。

1.13 selectStrategy

定义:

private final SelectStrategy selectStrategy;
  • 初始化:
    • 通过构造函数传入:
      this.selectStrategy = ObjectUtil.checkNotNull(strategy, "selectStrategy");
      
    • 通常为 DefaultSelectStrategy。
  • 作用:
    • 决定 Selector 的操作策略(select、selectNow 等)。
  • 使用场景:
    • 在 run() 方法中:
      strategy = selectStrategy.calculateStrategy(selectNowSupplier, hasTasks());
      
  • 设计理念:
    • 抽象选择逻辑,支持扩展性。

1.14 ioRatio

定义:

private volatile int ioRatio = 50;
  • 类型:int,使用 volatile 确保线程可见性。
  • 修饰符:private volatile,实例级别,可修改。
  • 初始化:默认 50(50% I/O,50% 任务)。
  • 作用:
    • 控制 I/O 处理和任务执行的时间比例(1-100)。
  • 使用场景:
    • 在 run() 方法中:
      final int ioRatio = this.ioRatio;
      if (ioRatio == 100) {
          // ...
      } else {
          runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
      }
      
    • 通过 setIoRatio(int) 修改:
      public void setIoRatio(int ioRatio) {
          if (ioRatio <= 0 || ioRatio > 100) {
              throw new IllegalArgumentException("ioRatio: " + ioRatio + " (expected: 0 < ioRatio <= 100)");
          }
          this.ioRatio = ioRatio;
      }
      
  • 设计理念:
    • 平衡 I/O 和任务处理,适配不同负载。
    • volatile 确保跨线程可见性。

1.15 cancelledKeys

定义:

private int cancelledKeys;
  • 初始化:隐式为 0。
  • 作用:
    • 跟踪已取消的 SelectionKey 数量。
    • 当达到 CLEANUP_INTERVAL(256)时,触发 selectAgain() 清理。
  • 使用场景:
    • 在 cancel(SelectionKey) 方法中:
      cancelledKeys++;
      if (cancelledKeys >= CLEANUP_INTERVAL) {
          cancelledKeys = 0;
          needsToSelectAgain = true;
      }
      
    • 在 run() 方法中重置:
      cancelledKeys = 0;
      
  • 设计理念:
    • 防止频繁 selectAgain(),优化性能。

1.16 needsToSelectAgain

定义:

private boolean needsToSelectAgain;
  • 初始化:隐式为 false。
  • 作用:
    • 指示是否需要调用 selectAgain() 清理已取消的 SelectionKey。
  • 使用场景:
    • 在 cancel(SelectionKey) 中设置:
      needsToSelectAgain = true;
      
    • 在 processSelectedKeysPlain 和 processSelectedKeysOptimized 中检查:
      if (needsToSelectAgain) {
          selectAgain();
      }
      
    • 在 run() 中重置:
      needsToSelectAgain = false;
      
  • 设计理念:
    • 确保及时清理已取消的键,避免冗余 select 调用。

2. 方法解析

以下是对 NioEventLoop 类中关键方法的详细解析,涵盖逻辑、输入输出、异常处理及与字段的交互。

2.1 构造函数

定义:

NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
             SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler,
             EventLoopTaskQueueFactory taskQueueFactory, EventLoopTaskQueueFactory tailTaskQueueFactory)
  • 作用:初始化 NioEventLoop 实例。
  • 输入:
    • parent:父级 NioEventLoopGroup。
    • executor:线程执行器(如 ThreadPerTaskExecutor)。
    • selectorProvider:NIO SelectorProvider。
    • strategy:选择策略。
    • rejectedExecutionHandler:任务队列溢出处理器。
    • taskQueueFactory, tailTaskQueueFactory:任务队列工厂。
  • 逻辑:
    • 调用 SingleThreadEventLoop 构造函数,初始化任务队列。
    • 初始化 provider 和 selectStrategy。
    • 调用 openSelector() 设置 selector 和 unwrappedSelector。
  • 字段交互:
    • 设置 provider、selectStrategy、selector、unwrappedSelector、selectedKeys。
  • 设计理念:确保线程安全初始化,支持自定义配置。

2.2 openSelector

定义:

private SelectorTuple openSelector()
  • 作用:创建并配置 NIO Selector。
  • 输出:SelectorTuple,包含 unwrappedSelector 和 selector。
  • 逻辑:
    • 使用 provider.openSelector() 创建 unwrappedSelector。
    • 若 DISABLE_KEY_SET_OPTIMIZATION 为 false,通过反射或 Unsafe 替换 Selector 的 selectedKeys 为 SelectedSelectionKeySet。
    • 返回优化或默认的 SelectorTuple。
  • 字段交互:
    • 设置 unwrappedSelector、selector、selectedKeys。
  • 设计理念:优化 SelectionKey 处理,处理兼容性问题。

2.3 run

定义:

@Override
protected void run()
  • 作用:驱动事件循环,处理 I/O 和任务。
  • 逻辑:
    • 无限循环,使用 selectStrategy 选择 select 或 selectNow。
    • 使用 nextWakeupNanos 设置 select 超时。
    • 通过 processSelectedKeys 处理 SelectionKey。
    • 根据 ioRatio 调用 runAllTasks 执行任务。
    • 处理空轮询和关闭逻辑。
  • 字段交互:
    • 使用 selectStrategy、selectNowSupplier、nextWakeupNanos、ioRatio、cancelledKeys、needsToSelectAgain、selector、selectedKeys。
  • 设计理念:平衡 I/O 和任务处理,确保鲁棒性。

2.4 select

定义:

private int select(long deadlineNanos) throws IOException
  • 作用:执行 Selector 选择操作,支持超时。
  • 输入:deadlineNanos(下一次唤醒时间)。
  • 输出:就绪的 SelectionKey 数量。
  • 逻辑:
    • 若 deadlineNanos == NONE,调用 selector.select()(无限阻塞)。
    • 否则,计算 timeoutMillis,调用 selector.select(timeoutMillis) 或 selectNow()。
  • 字段交互:使用 selector。
  • 设计理念:根据定时任务优化超时。

2.5 wakeup

定义:

@Override
protected void wakeup(boolean inEventLoop)
  • 作用:从其他线程唤醒 Selector。
  • 输入:inEventLoop(是否在事件循环线程中)。
  • 逻辑:
    • 若非事件循环线程且 nextWakeupNanos 非 AWAKE,设置 AWAKE 并调用 selector.wakeup()。
  • 字段交互:使用 nextWakeupNanos、selector。
  • 设计理念:线程安全唤醒,避免重复调用。

2.6 processSelectedKeys

定义:

private void processSelectedKeys()
  • 作用:处理就绪的 SelectionKey。
  • 逻辑:
    • 若 selectedKeys 非空,调用 processSelectedKeysOptimized()。
    • 否则,调用 processSelectedKeysPlain(selector.selectedKeys())。
  • 字段交互:使用 selectedKeys、selector。
  • 设计理念:优化键处理,支持高吞吐。

2.7 rebuildSelector

定义:

public void rebuildSelector()
  • 作用:重建 Selector,修复空轮询问题。
  • 逻辑:
    • 通过 openSelector() 创建新 Selector。
    • 将所有 Channel 注册到新 Selector。
    • 关闭旧 Selector。
  • 字段交互:更新 selector、unwrappedSelector、selectedKeys。
  • 设计理念:解决 Java NIO bug,确保稳定性。

2.8 其他方法

  • register:将 SelectableChannel 注册到 Selector。
  • setIoRatio, getIoRatio:管理 ioRatio。
  • cancel:取消 SelectionKey,更新 cancelledKeys。
  • closeAll:关闭所有注册的 Channel。
  • selectAgain:立即调用 selectNow() 清理键。

3. 源码

以下是 NioEventLoop.java 源码,添加了详细的中文注释,保留原始结构,确保清晰易读。



/**
 * {@link SingleThreadEventLoop} 的实现,负责将 {@link Channel} 注册到 Java NIO 的 {@link Selector},
 * 在单线程事件循环中进行 I/O 事件多路复用、任务调度和事件分发。每个 NioEventLoop 实例运行在一个独立线程,
 * 处理注册在其上的 Channel 的 I/O 事件(如连接、读写)以及提交的任务(普通任务和定时任务)。
 */
public final class NioEventLoop extends SingleThreadEventLoop {

    /**
     * 日志记录器,供所有 NioEventLoop 实例共享,用于记录调试信息、警告和错误。
     * - 初始化:通过 InternalLoggerFactory.getInstance(NioEventLoop.class) 创建,绑定到 NioEventLoop 类。
     * - 使用场景:记录 Selector 操作(如重建、异常)、空轮询问题、Channel 注册失败等。
     * - 示例:在 rebuildSelector0() 中记录 Selector 重建失败的警告;run() 中记录 CancelledKeyException。
     * - 设计理念:统一日志接口,支持用户配置日志输出(如文件、控制台),静态常量减少内存占用。
     */
    private static final InternalLogger logger = InternalLoggerFactory.getInstance(NioEventLoop.class);

    /**
     * 定义清理已取消 SelectionKey 的间隔,单位为取消次数。
     * - 初始化:硬编码为 256,一个经验值,平衡性能和清理频率。
     * - 作用:当 cancelledKeys 达到 256 时,设置 needsToSelectAgain = true,触发 selectAgain() 清理 Selector 中的无效键。
     * - 使用场景:在 cancel(SelectionKey) 方法中累加 cancelledKeys 并检查是否达到阈值。
     * - 设计理念:避免每次取消键都调用 selectAgain(),减少系统调用开销,提高性能。
     * - 注意:硬编码值通常无需调整,适合大多数场景。
     */
    private static final int CLEANUP_INTERVAL = 256; // XXX Hard-coded value, but won't need customization.

    /**
     * 控制是否禁用 SelectedSelectionKeySet 优化的标志,通过系统属性配置。
     * - 初始化:通过 SystemPropertyUtil.getBoolean("io.netty.noKeySetOptimization", false) 读取系统属性,默认 false(启用优化)。
     * - 作用:决定 openSelector() 是否使用 SelectedSelectionKeySet 替换 Selector 的默认 selectedKeys(HashSet)。
     * - 使用场景:在 openSelector() 中,若为 true,返回原生 Selector;否则尝试优化。
     * - 设计理念:提供配置灵活性,允许用户在调试或兼容性问题时禁用优化,默认启用以提升性能。
     * - 性能影响:优化后的 SelectedSelectionKeySet 使用数组实现,减少内存分配和迭代开销。
     */
    private static final boolean DISABLE_KEY_SET_OPTIMIZATION =
            SystemPropertyUtil.getBoolean("io.netty.noKeySetOptimization", false);

    /**
     * Selector.select() 连续过早返回的最小次数阈值,用于触发调试日志。
     * - 初始化:硬编码为 3,一个经验值,避免误判正常返回。
     * - 作用:在 selectReturnPrematurely() 中,若 selectCnt > 3,记录调试日志,提示可能的空轮询问题。
     * - 使用场景:在 run() 方法中检测 Selector 行为异常。
     * - 设计理念:与 SELECTOR_AUTO_REBUILD_THRESHOLD 配合,区分轻微和严重空轮询问题。
     */
    private static final int MIN_PREMATURE_SELECTOR_RETURNS = 3;

    /**
     * Selector 连续过早返回的重建阈值,用于触发 Selector 重建以解决空轮询 bug。
     * - 初始化:通过 SystemPropertyUtil.getInt("io.netty.selectorAutoRebuildThreshold", 512) 读取系统属性,默认 512。
     *   若值小于 MIN_PREMATURE_SELECTOR_RETURNS(3),设为 0(禁用重建)。
     * - 作用:当 selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD 时,调用 rebuildSelector() 重建 Selector。
     * - 使用场景:在 unexpectedSelectorWakeup() 中检查空轮询问题。
     * - 设计理念:解决 Java NIO 的空轮询 bug(如 https://github.com/netty/netty/issues/2426),
     *   默认 512 次是经验值,平衡性能和稳定性;支持用户通过系统属性调整或禁用。
     * - 性能影响:重建 Selector 涉及 Channel 迁移,需谨慎设置阈值。
     */
    private static final int SELECTOR_AUTO_REBUILD_THRESHOLD;

    /**
     * 静态初始化块,处理 JDK NIO bug 和配置重建阈值。
     * - 针对 Java 6 的 NIO bug(如 JDK-6427854),设置 sun.nio.ch.bugLevel 属性。
     * - 初始化 SELECTOR_AUTO_REBUILD_THRESHOLD,确保不低于 MIN_PREMATURE_SELECTOR_RETURNS。
     * - 记录调试日志,输出 DISABLE_KEY_SET_OPTIMIZATION 和 SELECTOR_AUTO_REBUILD_THRESHOLD 的值。
     * - 设计理念:增强兼容性,确保 Netty 在不同 Java 版本下稳定运行。
     */
    static {
        if (PlatformDependent.javaVersion() < 7) {
            final String key = "sun.nio.ch.bugLevel";
            final String bugLevel = SystemPropertyUtil.get(key);
            if (bugLevel == null) {
                try {
                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
                        @Override
                        public Void run() {
                            System.setProperty(key, "");
                            return null;
                        }
                    });
                } catch (final SecurityException e) {
                    logger.debug("无法获取/设置系统属性: " + key, e);
                }
            }
        }
        int selectorAutoRebuildThreshold = SystemPropertyUtil.getInt("io.netty.selectorAutoRebuildThreshold", 512);
        if (selectorAutoRebuildThreshold < MIN_PREMATURE_SELECTOR_RETURNS) {
            selectorAutoRebuildThreshold = 0;
        }
        SELECTOR_AUTO_REBUILD_THRESHOLD = selectorAutoRebuildThreshold;

        if (logger.isDebugEnabled()) {
            logger.debug("-Dio.netty.noKeySetOptimization: {}", DISABLE_KEY_SET_OPTIMIZATION);
            logger.debug("-Dio.netty.selectorAutoRebuildThreshold: {}", SELECTOR_AUTO_REBUILD_THRESHOLD);
        }
    }

    /**
     * 提供 selectNow() 的函数式接口封装,用于 selectStrategy 判断。
     * - 初始化:匿名类实现,调用 selectNow() 方法返回就绪的 SelectionKey 数量。
     * - 作用:供 selectStrategy.calculateStrategy() 使用,检查是否有立即就绪的 I/O 事件。
     * - 使用场景:在 run() 方法中,若 hasTasks() 为 true,调用 selectNowSupplier.get() 执行非阻塞 select。
     * - 设计理念:抽象 selectNow() 调用,方便扩展 selectStrategy;异常由 run() 捕获,增强鲁棒性。
     * - 性能优化:避免直接调用 selectNow(),提高代码可维护性。
     */
    private final IntSupplier selectNowSupplier = new IntSupplier() {
        @Override
        public int get() throws Exception {
            return selectNow();
        }
    };

    /**
     * NIO Selector,负责 I/O 事件多路复用。
     * - 初始化:在构造函数中通过 openSelector() 设置,可能为:
     *   - SelectedSelectionKeySetSelector(优化后的包装类,若启用 SelectedSelectionKeySet)。
     *   - 原生 Selector(若禁用优化或优化失败)。
     * - 作用:监控注册 Channel 的 I/O 事件(如 OP_READ、OP_WRITE、OP_ACCEPT)。
     * - 使用场景:
     *   - run() 方法中调用 select() 和 selectNow()。
     *   - processSelectedKeys() 处理就绪的 SelectionKey。
     *   - wakeup() 调用 selector.wakeup() 唤醒阻塞。
     *   - rebuildSelector0() 迁移到新 Selector。
     * - 设计理念:封装 NIO Selector,支持优化(如 SelectedSelectionKeySet)和重建,适应高并发场景。
     * - 线程安全:仅由事件循环线程访问,无需同步。
     */
    private Selector selector;

    /**
     * 原生 NIO Selector,未经 SelectedSelectionKeySet 优化。
     * - 初始化:在 openSelector() 中通过 provider.openSelector() 创建。
     * - 作用:
     *   - 用于直接注册 Channel(register0() 方法)。
     *   - 优化失败或禁用时作为 selector 的回退。
     *   - 在 Selector 重建时迁移 Channel。
     * - 使用场景:
     *   - register0() 中注册 Channel。
     *   - rebuildSelector0() 迁移 Channel 注册。
     * - 设计理念:分离原生和优化 Selector,增强兼容性和灵活性。
     * - 线程安全:仅由事件循环线程访问。
     */
    private Selector unwrappedSelector;

    /**
     * 基于数组的就绪 SelectionKey 集合,用于优化 Selector 性能。
     * - 初始化:在 openSelector() 中创建,若优化失败或禁用则为 null。
     * - 作用:替换 Selector 的默认 selectedKeys(HashSet),使用数组存储就绪 SelectionKey,减少内存分配和迭代开销。
     * - 使用场景:
     *   - processSelectedKeys() 中若 selectedKeys 非空,调用 processSelectedKeysOptimized()。
     *   - processSelectedKeysOptimized() 迭代 selectedKeys.keys 数组。
     * - 设计理念:优化高吞吐场景的 SelectionKey 处理,降低 CPU 和内存开销;可通过 DISABLE_KEY_SET_OPTIMIZATION 禁用。
     * - 性能优化:数组比 HashSet 迭代更快,适合高并发 I/O 处理。
     */
    private SelectedSelectionKeySet selectedKeys;

    /**
     * NIO SelectorProvider,用于创建 Selector 和 Channel。
     * - 初始化:在构造函数中传入,确保非空(ObjectUtil.checkNotNull)。
     * - 作用:提供 NIO 核心组件的创建接口,通常为 SelectorProvider.provider()(默认实现)。
     * - 使用场景:在 openSelector() 中创建 unwrappedSelector。
     * - 设计理念:抽象 NIO 提供者,支持自定义实现(实际很少使用),确保兼容性。
     * - 线程安全:SelectorProvider 本身线程安全,provider 仅用于初始化。
     */
    private final SelectorProvider provider;

    /**
     * 表示事件循环已唤醒(不阻塞在 select 中)的常量。
     * - 初始化:硬编码为 -1L。
     * - 作用:用于 nextWakeupNanos,表示 Selector 已唤醒,不需阻塞。
     * - 使用场景:
     *   - run() 中通过 nextWakeupNanos.lazySet(AWAKE) 标记唤醒状态。
     *   - wakeup() 中通过 nextWakeupNanos.getAndSet(AWAKE) 检查状态。
     * - 设计理念:简单常量,清晰表示非阻塞状态,优化唤醒逻辑。
     */
    private static final long AWAKE = -1L;

    /**
     * 表示无定时任务,Selector 可无限期阻塞的常量。
     * - 初始化:硬编码为 Long.MAX_VALUE。
     * - 作用:用于 nextWakeupNanos,表示无定时任务,select() 可无限阻塞。
     * - 使用场景:
     *   - run() 中若无定时任务,设置 curDeadlineNanos = NONE。
     *   - select() 中若 deadlineNanos == NONE,调用 selector.select()。
     * - 设计理念:确保无任务时最小化 CPU 使用,优化阻塞行为。
     */
    private static final long NONE = Long.MAX_VALUE;

    /**
     * 存储 Selector 下一次唤醒时间(纳秒),控制 select 超时和唤醒逻辑。
     * - 初始化:设为 AWAKE(-1L),表示初始为唤醒状态。
     * - 作用:
     *   - 表示三种状态:
     *     - AWAKE (-1L):事件循环已唤醒。
     *     - NONE (Long.MAX_VALUE):无定时任务,select 可无限阻塞。
     *     - 其他值:最早定时任务的截止时间(纳秒)。
     *   - 控制 select() 的超时时间,协调 I/O 和定时任务。
     *   - 支持外部线程通过 wakeup() 唤醒 Selector。
     * - 使用场景:
     *   - run() 中设置 nextWakeupNanos.set(curDeadlineNanos) 和 lazySet(AWAKE)。
     *   - wakeup() 中通过 getAndSet(AWAKE) 判断是否需要唤醒。
     *   - beforeScheduledTaskSubmitted() 和 afterScheduledTaskSubmitted() 检查定时任务是否需要更早唤醒。
     * - 设计理念:
     *   - 使用 AtomicLong 确保线程安全,允许外部线程安全修改。
     *   - lazySet(AWAKE) 优化性能,减少内存屏障开销。
     *   - 替代 Netty 早期版本的 wakenUp 字段,简化状态管理。
     * - 性能优化:纳秒精度支持精确的任务调度,lazySet 减少同步开销。
     */
    private final AtomicLong nextWakeupNanos = new AtomicLong(AWAKE);

    /**
     * 选择策略,决定 Selector 的操作方式(如 select 或 selectNow)。
     * - 初始化:在构造函数中传入,确保非空(ObjectUtil.checkNotNull),通常为 DefaultSelectStrategy。
     * - 作用:根据任务队列状态和 selectNowSupplier 决定执行阻塞 select、非阻塞 selectNow 或其他操作。
     * - 使用场景:在 run() 中调用 calculateStrategy() 确定策略。
     * - 设计理念:抽象选择逻辑,支持扩展(如支持 epoll 或其他模型),提高灵活性。
     */
    private final SelectStrategy selectStrategy;

    /**
     * I/O 处理与任务执行的时间比例,控制事件循环的资源分配。
     * - 初始化:默认 50,表示 50% 时间用于 I/O,50% 用于任务。
     * - 作用:范围 1-100,决定 processSelectedKeys() 和 runAllTasks() 的时间分配。
     * - 使用场景:
     *   - run() 中根据 ioRatio 决定任务执行时间。
     *   - setIoRatio() 和 getIoRatio() 提供外部配置接口。
     * - 设计理念:
     *   - 平衡 I/O 和任务处理,适配不同负载(如 I/O 密集或任务密集)。
     *   - volatile 确保多线程修改可见性。
     * - 性能优化:动态调整比例,优化吞吐量和延迟。
     */
    private volatile int ioRatio = 50;

    /**
     * 跟踪已取消的 SelectionKey 数量,用于触发清理。
     * - 初始化:隐式为 0。
     * - 作用:记录 cancel(SelectionKey) 调用次数,当达到 CLEANUP_INTERVAL(256)时,触发 selectAgain()。
     * - 使用场景:
     *   - cancel() 中累加 cancelledKeys。
     *   - run() 中重置为 0。
     * - 设计理念:延迟清理,减少 selectAgain() 调用频率,优化性能。
     * - 线程安全:仅由事件循环线程修改,无需同步。
     */
    private int cancelledKeys;

    /**
     * 指示是否需要调用 selectAgain() 清理已取消的 SelectionKey。
     * - 初始化:隐式为 false。
     * - 作用:当 cancelledKeys 达到 CLEANUP_INTERVAL 或其他条件时,设为 true,触发清理。
     * - 使用场景:
     *   - cancel() 中设置 needsToSelectAgain = true。
     *   - processSelectedKeysPlain() 和 processSelectedKeysOptimized() 检查并调用 selectAgain()。
     *   - run() 中重置为 false。
     * - 设计理念:确保及时清理无效键,避免 Selector 状态不一致,同时优化调用频率。
     */
    private boolean needsToSelectAgain;

    /**
     * 构造函数,初始化 NioEventLoop 实例。
     * - 参数:
     *   - parent:父级 NioEventLoopGroup,管理多个 EventLoop。
     *   - executor:线程执行器,通常为 ThreadPerTaskExecutor,运行事件循环。
     *   - selectorProvider:NIO SelectorProvider,创建 Selector 和 Channel。
     *   - strategy:选择策略,决定 select 操作。
     *   - rejectedExecutionHandler:任务队列溢出处理器。
     *   - taskQueueFactory:主任务队列工厂。
     *   - tailTaskQueueFactory:尾部任务队列工厂。
     * - 逻辑:
     *   - 调用父类 SingleThreadEventLoop 构造函数,初始化任务队列。
     *   - 检查并设置 provider 和 selectStrategy。
     *   - 调用 openSelector() 初始化 selector 和 unwrappedSelector。
     * - 字段交互:设置 provider、selectStrategy、selector、unwrappedSelector、selectedKeys。
     * - 异常处理:通过 ObjectUtil.checkNotNull 确保参数非空。
     * - 设计理念:确保线程安全初始化,支持自定义配置,适应不同场景。
     */
    NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
                 SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler,
                 EventLoopTaskQueueFactory taskQueueFactory, EventLoopTaskQueueFactory tailTaskQueueFactory) {
        super(parent, executor, false, newTaskQueue(taskQueueFactory), newTaskQueue(tailTaskQueueFactory),
                rejectedExecutionHandler);
        this.provider = ObjectUtil.checkNotNull(selectorProvider, "selectorProvider");
        this.selectStrategy = ObjectUtil.checkNotNull(strategy, "selectStrategy");
        final SelectorTuple selectorTuple = openSelector();
        this.selector = selectorTuple.selector;
        this.unwrappedSelector = selectorTuple.unwrappedSelector;
    }

    /**
     * 创建任务队列,若工厂为 null 则使用默认 MpscQueue。
     * - 参数:queueFactory,任务队列工厂。
     * - 返回:Queue<Runnable>,任务队列。
     * - 逻辑:若 factory 为 null,调用 newTaskQueue0() 创建 MpscQueue;否则使用 factory 创建。
     * - 设计理念:支持自定义队列实现,默认使用高性能 MpscQueue,适合单线程模型。
     */
    private static Queue<Runnable> newTaskQueue(EventLoopTaskQueueFactory queueFactory) {
        if (queueFactory == null) {
            return newTaskQueue0(DEFAULT_MAX_PENDING_TASKS);
        }
        return queueFactory.newTaskQueue(DEFAULT_MAX_PENDING_TASKS);
    }

    /**
     * 内部方法,创建指定容量的 MpscQueue。
     * - 参数:maxPendingTasks,最大任务容量。
     * - 返回:Queue<Runnable>,MpscQueue 实例。
     * - 逻辑:根据 maxPendingTasks 使用 PlatformDependent 创建无界或有界队列。
     * - 设计理念:MpscQueue 优化单生产者多消费者场景,适合事件循环。
     */
    private static Queue<Runnable> newTaskQueue0(int maxPendingTasks) {
        return maxPendingTasks == Integer.MAX_VALUE ? PlatformDependent.<Runnable>newMpscQueue()
                : PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks);
    }

    /**
     * Selector 元组类,存储原生和优化后的 Selector。
     * - 字段:
     *   - unwrappedSelector:原生 Selector。
     *   - selector:优化后的 Selector 或原生 Selector。
     * - 构造函数:支持单一 Selector 或原生+优化 Selector。
     * - 设计理念:封装 Selector 对,简化 openSelector() 的返回值。
     */
    private static final class SelectorTuple {
        final Selector unwrappedSelector;
        final Selector selector;

        SelectorTuple(Selector unwrappedSelector) {
            this.unwrappedSelector = unwrappedSelector;
            this.selector = unwrappedSelector;
        }

        SelectorTuple(Selector unwrappedSelector, Selector selector) {
            this.unwrappedSelector = unwrappedSelector;
            this.selector = selector;
        }
    }

    /**
     * 创建并配置 Selector,支持 SelectedSelectionKeySet 优化。
     * - 返回:SelectorTuple,包含 unwrappedSelector 和 selector。
     * - 逻辑:
     *   - 使用 provider.openSelector() 创建 unwrappedSelector。
     *   - 若 DISABLE_KEY_SET_OPTIMIZATION 为 true,返回原生 Selector。
     *   - 否则,通过反射或 Unsafe 替换 Selector 的 selectedKeys 和 publicSelectedKeys 为 SelectedSelectionKeySet。
     *   - 若优化失败,selectedKeys 设为 null,回退到原生 Selector。
     * - 字段交互:设置 unwrappedSelector、selector、selectedKeys。
     * - 异常处理:捕获 IOException、NoSuchFieldException、IllegalAccessException,记录日志并回退。
     * - 设计理念:优化 SelectionKey 处理,减少内存分配;支持兼容性回退。
     * - 性能优化:SelectedSelectionKeySet 使用数组,显著提高高并发性能。
     */
    private SelectorTuple openSelector() {
        final Selector unwrappedSelector;
        try {
            unwrappedSelector = provider.openSelector();
        } catch (IOException e) {
            throw new ChannelException("无法打开新的 Selector", e);
        }
        if (DISABLE_KEY_SET_OPTIMIZATION) {
            return new SelectorTuple(unwrappedSelector);
        }
        Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                try {
                    return Class.forName(
                            "sun.nio.ch.SelectorImpl",
                            false,
                            PlatformDependent.getSystemClassLoader());
                } catch (Throwable cause) {
                    return cause;
                }
            }
        });
        if (!(maybeSelectorImplClass instanceof Class) ||
            !((Class<?>) maybeSelectorImplClass).isAssignableFrom(unwrappedSelector.getClass())) {
            if (maybeSelectorImplClass instanceof Throwable) {
                Throwable t = (Throwable) maybeSelectorImplClass;
                logger.trace("无法将特殊 java.util.Set 注入到: {}", unwrappedSelector, t);
            }
            return new SelectorTuple(unwrappedSelector);
        }
        final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
        final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
        Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                try {
                    Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
                    Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
                    if (PlatformDependent.javaVersion() >= 9 && PlatformDependent.hasUnsafe()) {
                        long selectedKeysFieldOffset = PlatformDependent.objectFieldOffset(selectedKeysField);
                        long publicSelectedKeysFieldOffset = PlatformDependent.objectFieldOffset(publicSelectedKeysField);
                        if (selectedKeysFieldOffset != -1 && publicSelectedKeysFieldOffset != -1) {
                            PlatformDependent.putObject(unwrappedSelector, selectedKeysFieldOffset, selectedKeySet);
                            PlatformDependent.putObject(unwrappedSelector, publicSelectedKeysFieldOffset, selectedKeySet);
                            return null;
                        }
                    }
                    Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField, true);
                    if (cause != null) {
                        return cause;
                    }
                    cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField, true);
                    if (cause != null) {
                        return cause;
                    }
                    selectedKeysField.set(unwrappedSelector, selectedKeySet);
                    publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
                    return null;
                } catch (NoSuchFieldException e) {
                    return e;
                } catch (IllegalAccessException e) {
                    return e;
                }
            }
        });
        if (maybeException instanceof Exception) {
            selectedKeys = null;
            Exception e = (Exception) maybeException;
            logger.trace("无法将特殊 java.util.Set 注入到: {}", unwrappedSelector, e);
            return new SelectorTuple(unwrappedSelector);
        }
        selectedKeys = selectedKeySet;
        logger.trace("成功将特殊 java.util.Set 注入到: {}", unwrappedSelector);
        return new SelectorTuple(unwrappedSelector, new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet));
    }

    /**
     * 返回此 NioEventLoop 使用的 SelectorProvider。
     * - 逻辑:直接返回 provider 字段。
     * - 设计理念:提供访问接口,便于外部获取 NIO 提供者。
     */
    public SelectorProvider selectorProvider() {
        return provider;
    }

    /**
     * 创建新的任务队列,覆盖父类方法。
     * - 逻辑:调用 newTaskQueue0() 创建 MpscQueue。
     * - 设计理念:支持自定义容量,优化任务存储。
     */
    @Override
    protected Queue<Runnable> newTaskQueue(int maxPendingTasks) {
        return newTaskQueue0(maxPendingTasks);
    }

    /**
     * 将 SelectableChannel 注册到 Selector,指定兴趣操作和任务。
     * - 参数:
     *   - ch:SelectableChannel,如 SocketChannel 或 ServerSocketChannel。
     *   - interestOps:兴趣操作(如 OP_READ、OP_WRITE)。
     *   - task:NioTask,处理 Channel 事件。
     * - 逻辑:
     *   - 检查参数非空和有效性。
     *   - 若已关闭,抛出 IllegalStateException。
     *   - 若在事件循环线程,直接调用 register0();否则提交任务到事件循环。
     * - 异常处理:捕获 InterruptedException,恢复线程中断状态。
     * - 设计理念:确保注册操作线程安全,统一在事件循环线程执行。
     */
    public void register(final SelectableChannel ch, final int interestOps, final NioTask<?> task) {
        ObjectUtil.checkNotNull(ch, "ch");
        if (interestOps == 0) {
            throw new IllegalArgumentException("interestOps 必须非零。");
        }
        if ((interestOps & ~ch.validOps()) != 0) {
            throw new IllegalArgumentException(
                    "无效的 interestOps: " + interestOps + "(有效值: " + ch.validOps() + ')');
        }
        ObjectUtil.checkNotNull(task, "task");
        if (isShutdown()) {
            throw new IllegalStateException("事件循环已关闭");
        }
        if (inEventLoop()) {
            register0(ch, interestOps, task);
        } else {
            try {
                submit(new Runnable() {
                    @Override
                    public void run() {
                        register0(ch, interestOps, task);
                    }
                }).sync();
            } catch (InterruptedException ignore) {
                Thread.currentThread().interrupt();
            }
        }
    }

    /**
     * 内部方法,执行 Channel 注册。
     * - 参数:ch、interestOps、task,与 register() 相同。
     * - 逻辑:调用 ch.register(unwrappedSelector, interestOps, task) 注册 Channel。
     * - 异常处理:捕获 Exception,抛出 EventLoopException。
     * - 设计理念:使用 unwrappedSelector 确保注册不受优化影响,保持兼容性。
     */
    private void register0(SelectableChannel ch, int interestOps, NioTask<?> task) {
        try {
            ch.register(unwrappedSelector, interestOps, task);
        } catch (Exception e) {
            throw new EventLoopException("无法注册 Channel", e);
        }
    }

    /**
     * 获取当前的 I/O 比例。
     * - 返回:ioRatio,1-100。
     * - 逻辑:直接返回 ioRatio 字段。
     * - 设计理念:提供外部访问接口,便于监控和调整。
     */
    public int getIoRatio() {
        return ioRatio;
    }

    /**
     * 设置 I/O 比例,控制 I/O 和任务的时间分配。
     * - 参数:ioRatio,1-100。
     * - 逻辑:检查范围有效性,更新 ioRatio。
     * - 异常处理:抛出 IllegalArgumentException 若范围无效。
     * - 设计理念:支持动态调整,适配不同负载场景。
     */
    public void setIoRatio(int ioRatio) {
        if (ioRatio <= 0 || ioRatio > 100) {
            throw new IllegalArgumentException("ioRatio: " + ioRatio + " (预期: 0 < ioRatio <= 100)");
        }
        this.ioRatio = ioRatio;
    }

    /**
     * 重建 Selector,解决空轮询问题。
     * - 逻辑:
     *   - 若不在事件循环线程,提交任务到事件循环。
     *   - 否则直接调用 rebuildSelector0()。
     * - 设计理念:确保线程安全,统一在事件循环线程执行重建。
     */
    public void rebuildSelector() {
        if (!inEventLoop()) {
            execute(new Runnable() {
                @Override
                public void run() {
                    rebuildSelector0();
                }
            });
            return;
        }
        rebuildSelector0();
    }

    /**
     * 返回注册的 Channel 数量。
     * - 返回:selector.keys().size() - cancelledKeys。
     * - 逻辑:计算当前有效 Channel 数量,排除已取消的键。
     * - 设计理念:提供监控接口,方便外部了解事件循环负载。
     */
    @Override
    public int registeredChannels() {
        return selector.keys().size() - cancelledKeys;
    }

    /**
     * 返回注册 Channel 的迭代器。
     * - 返回:Iterator<Channel>,遍历有效 Channel。
     * - 逻辑:
     *   - 若 selector.keys() 为空,返回空迭代器。
     *   - 否则创建迭代器,过滤有效 SelectionKey 并提取 AbstractNioChannel。
     * - 设计理念:支持外部遍历 Channel,优化空集合处理。
     */
    @Override
    public Iterator<Channel> registeredChannelsIterator() {
        assert inEventLoop();
        final Set<SelectionKey> keys = selector.keys();
        if (keys.isEmpty()) {
            return ChannelsReadOnlyIterator.empty();
        }
        return new Iterator<Channel>() {
            final Iterator<SelectionKey> selectionKeyIterator = ObjectUtil.checkNotNull(keys, "selectionKeys").iterator();
            Channel next;
            boolean isDone;

            @Override
            public boolean hasNext() {
                if (isDone) {
                    return false;
                }
                Channel cur = next;
                if (cur == null) {
                    cur = next = nextOrDone();
                    return cur != null;
                }
                return true;
            }

            @Override
            public Channel next() {
                if (isDone) {
                    throw new NoSuchElementException();
                }
                Channel cur = next;
                if (cur == null) {
                    cur = nextOrDone();
                    if (cur == null) {
                        throw new NoSuchElementException();
                    }
                }
                next = nextOrDone();
                return cur;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("remove");
            }

            private Channel nextOrDone() {
                Iterator<SelectionKey> it = selectionKeyIterator;
                while (it.hasNext()) {
                    SelectionKey key = it.next();
                    if (key.isValid()) {
                        Object attachment = key.attachment();
                        if (attachment instanceof AbstractNioChannel) {
                            return (AbstractNioChannel) attachment;
                        }
                    }
                }
                isDone = true;
                return null;
            }
        };
    }

    /**
     * 内部方法,执行 Selector 重建。
     * - 逻辑:
     *   - 创建新 Selector(newSelectorTuple)。
     *   - 遍历旧 Selector 的键,迁移有效 Channel 到新 Selector。
     *   - 更新 selector 和 unwrappedSelector。
     *   - 关闭旧 Selector。
     * - 字段交互:更新 selector、unwrappedSelector、selectedKeys。
     * - 异常处理:
     *   - 捕获创建 Selector 的异常,记录警告。
     *   - 捕获迁移 Channel 的异常,关闭失败的 Channel。
     *   - 捕获关闭旧 Selector 的异常,记录警告。
     * - 设计理念:解决 Java NIO 空轮询 bug,确保事件循环稳定性。
     */
    private void rebuildSelector0() {
        final Selector oldSelector = selector;
        final SelectorTuple newSelectorTuple;
        if (oldSelector == null) {
            return;
        }
        try {
            newSelectorTuple = openSelector();
        } catch (Exception e) {
            logger.warn("无法创建新的 Selector。", e);
            return;
        }
        int nChannels = 0;
        for (SelectionKey key : oldSelector.keys()) {
            Object a = key.attachment();
            try {
                if (!key.isValid() || key.channel().keyFor(newSelectorTuple.unwrappedSelector) != null) {
                    continue;
                }
                int interestOps = key.interestOps();
                key.cancel();
                SelectionKey newKey = key.channel().register(newSelectorTuple.unwrappedSelector, interestOps, a);
                if (a instanceof AbstractNioChannel) {
                    ((AbstractNioChannel) a).selectionKey = newKey;
                }
                nChannels++;
            } catch (Exception e) {
                logger.warn("无法将 Channel 重新注册到新 Selector。", e);
                if (a instanceof AbstractNioChannel) {
                    AbstractNioChannel ch = (AbstractNioChannel) a;
                    ch.unsafe().close(ch.unsafe().voidPromise());
                } else {
                    @SuppressWarnings("unchecked")
                    NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
                    invokeChannelUnregistered(task, key, e);
                }
            }
        }
        selector = newSelectorTuple.selector;
        unwrappedSelector = newSelectorTuple.unwrappedSelector;
        try {
            oldSelector.close();
        } catch (Throwable t) {
            if (logger.isWarnEnabled()) {
                logger.warn("无法关闭旧 Selector。", t);
            }
        }
        if (logger.isInfoEnabled()) {
            logger.info("成功迁移 {} 个 Channel 到新 Selector。", nChannels);
        }
    }

    /**
     * 核心事件循环方法,驱动 I/O 事件和任务处理。
     * - 逻辑:
     *   - 无限循环,调用 selectStrategy.calculateStrategy() 决定 select 操作。
     *   - 根据 nextWakeupNanos 设置 select 超时,处理 I/O 事件。
     *   - 根据 ioRatio 分配时间,调用 processSelectedKeys() 和 runAllTasks()。
     *   - 检测空轮询问题(selectReturnPrematurely 和 unexpectedSelectorWakeup)。
     *   - 处理关闭逻辑(isShuttingDown、closeAll、confirmShutdown)。
     * - 字段交互:使用 selectStrategy、selectNowSupplier、nextWakeupNanos、ioRatio、cancelledKeys、needsToSelectAgain、selector、selectedKeys。
     * - 异常处理:
     *   - 捕获 IOException,重建 Selector。
     *   - 捕获 CancelledKeyException,记录日志。
     *   - 捕获 Error,直接抛出。
     *   - 捕获其他 Throwable,调用 handleLoopException。
     * - 设计理念:实现 Reactor 模型,平衡 I/O 和任务处理,优化性能和稳定性。
     */
    @Override
    protected void run() {
        int selectCnt = 0; // 跟踪 select() 调用次数,检测空轮询。
        for (;;) {
            try {
                int strategy;
                try {
                    // 根据任务队列和 selectNowSupplier 决定选择策略。
                    strategy = selectStrategy.calculateStrategy(selectNowSupplier, hasTasks());
                    switch (strategy) {
                        case SelectStrategy.CONTINUE:
                            continue;
                        case SelectStrategy.BUSY_WAIT:
                            // NIO 不支持忙等待,退回到 SELECT。
                        case SelectStrategy.SELECT:
                            // 获取最早定时任务的截止时间。
                            long curDeadlineNanos = nextScheduledTaskDeadlineNanos();
                            if (curDeadlineNanos == -1L) {
                                curDeadlineNanos = NONE; // 无定时任务。
                            }
                            // 设置 Selector 下一次唤醒时间。
                            nextWakeupNanos.set(curDeadlineNanos);
                            try {
                                if (!hasTasks()) {
                                    // 若无任务,执行带超时的 select。
                                    strategy = select(curDeadlineNanos);
                                }
                            } finally {
                                // 标记事件循环为唤醒状态,防止不必要唤醒。
                                nextWakeupNanos.lazySet(AWAKE);
                            }
                            // 继续执行。
                        default:
                    }
                } catch (IOException e) {
                    // Selector 异常时重建,重置 selectCnt。
                    rebuildSelector0();
                    selectCnt = 0;
                    handleLoopException(e);
                    continue;
                }
                selectCnt++;
                cancelledKeys = 0;
                needsToSelectAgain = false;
                final int ioRatio = this.ioRatio;
                boolean ranTasks;
                if (ioRatio == 100) {
                    try {
                        if (strategy > 0) {
                            processSelectedKeys();
                        }
                    } finally {
                        ranTasks = runAllTasks();
                    }
                } else if (strategy > 0) {
                    final long ioStartTime = System.nanoTime();
                    try {
                        processSelectedKeys();
                    } finally {
                        final long ioTime = System.nanoTime() - ioStartTime;
                        ranTasks = runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
                    }
                } else {
                    ranTasks = runAllTasks(0); // 无 I/O 事件时运行最少任务。
                }
                if (selectReturnPrematurely(selectCnt, ranTasks, strategy)) {
                    selectCnt = 0;
                } else if (unexpectedSelectorWakeup(selectCnt)) {
                    selectCnt = 0;
                }
            } catch (CancelledKeyException e) {
                if (logger.isDebugEnabled()) {
                    logger.debug(CancelledKeyException.class.getSimpleName() + " 由 Selector 引发 {} - JDK bug?", selector, e);
                }
            } catch (Error e) {
                throw e;
            } catch (Throwable t) {
                handleLoopException(t);
            } finally {
                try {
                    if (isShuttingDown()) {
                        closeAll();
                        if (confirmShutdown()) {
                            return;
                        }
                    }
                } catch (Error e) {
                    throw e;
                } catch (Throwable t) {
                    handleLoopException(t);
                }
            }
        }
    }

    /**
     * 检查 select 是否过早返回,若是则重置 selectCnt。
     * - 参数:selectCnt(select 调用次数),ranTasks(是否执行了任务),strategy(选择策略)。
     * - 返回:boolean,是否过早返回。
     * - 逻辑:若 ranTasks 或 strategy > 0,记录调试日志(若 selectCnt > MIN_PREMATURE_SELECTOR_RETURNS),返回 true。
     * - 设计理念:检测潜在空轮询问题,触发日志便于调试。
     */
    private boolean selectReturnPrematurely(int selectCnt, boolean ranTasks, int strategy) {
        if (ranTasks || strategy > 0) {
            if (selectCnt > MIN_PREMATURE_SELECTOR_RETURNS && logger.isDebugEnabled()) {
                logger.debug("Selector.select() 连续 {} 次过早返回,Selector: {}.", selectCnt - 1, selector);
            }
            return true;
        }
        return false;
    }

    /**
     * 检测意外的 Selector 唤醒,必要时重建。
     * - 参数:selectCnt,select 调用次数。
     * - 返回:boolean,是否触发重建。
     * - 逻辑:
     *   - 若线程被中断,返回 true。
     *   - 若 selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD,触发 rebuildSelector()。
     * - 设计理念:解决 Java NIO 空轮询 bug,确保稳定性。
     */
    private boolean unexpectedSelectorWakeup(int selectCnt) {
        if (Thread.interrupted()) {
            if (logger.isDebugEnabled()) {
                logger.debug("Selector.select() 因线程中断过早返回...");
            }
            return true;
        }
        if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 && selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {
            logger.warn("Selector.select() 连续 {} 次过早返回,正在重建 Selector {}.", selectCnt, selector);
            rebuildSelector();
            return true;
        }
        return false;
    }

    /**
     * 处理事件循环中的意外异常,休眠 1 秒防止 CPU 过载。
     * - 参数:t,异常。
     * - 逻辑:记录警告日志,休眠 1 秒,忽略 InterruptedException。
     * - 设计理念:防止异常导致事件循环高 CPU 占用,确保稳定性。
     */
    private static void handleLoopException(Throwable t) {
        logger.warn("选择器循环中发生意外异常。", t);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // 忽略。
        }
    }

    /**
     * 处理就绪的 SelectionKey,使用优化或默认实现。
     * - 逻辑:
     *   - 若 selectedKeys 非空,调用 processSelectedKeysOptimized()。
     *   - 否则调用 processSelectedKeysPlain(selector.selectedKeys())。
     * - 字段交互:使用 selectedKeys、selector。
     * - 设计理念:根据优化状态选择高效处理方式,支持高吞吐。
     */
    private void processSelectedKeys() {
        if (selectedKeys != null) {
            processSelectedKeysOptimized();
        } else {
            processSelectedKeysPlain(selector.selectedKeys());
        }
    }

    /**
     * 清理资源,关闭 Selector。
     * - 逻辑:调用 selector.close(),捕获 IOException 并记录警告。
     * - 设计理念:确保事件循环关闭时释放资源。
     */
    @Override
    protected void cleanup() {
        try {
            selector.close();
        } catch (IOException e) {
            logger.warn("无法关闭 Selector。", e);
        }
    }

    /**
     * 取消 SelectionKey,跟踪取消数量以触发清理。
     * - 参数:key,SelectionKey。
     * - 逻辑:
     *   - 调用 key.cancel()。
     *   - 累加 cancelledKeys,若达到 CLEANUP_INTERVAL,设置 needsToSelectAgain。
     * - 设计理念:延迟清理,优化性能。
     */
    void cancel(SelectionKey key) {
        key.cancel();
        cancelledKeys++;
        if (cancelledKeys >= CLEANUP_INTERVAL) {
            cancelledKeys = 0;
            needsToSelectAgain = true;
        }
    }

    /**
     * 使用默认 HashSet 处理 SelectionKey。
     * - 参数:selectedKeys,Selector 的就绪键集合。
     * - 逻辑:
     *   - 遍历 selectedKeys,处理每个键(AbstractNioChannel 或 NioTask)。
     *   - 若 needsToSelectAgain 为 true,调用 selectAgain() 清理。
     * - 设计理念:兼容默认 Selector 实现,处理非优化场景。
     */
    private void processSelectedKeysPlain(Set<SelectionKey> selectedKeys) {
        if (selectedKeys.isEmpty()) {
            return;
        }
        Iterator<SelectionKey> i = selectedKeys.iterator();
        for (;;) {
            final SelectionKey k = i.next();
            final Object a = k.attachment();
            i.remove();
            if (a instanceof AbstractNioChannel) {
                processSelectedKey(k, (AbstractNioChannel) a);
            } else {
                @SuppressWarnings("unchecked")
                NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
                processSelectedKey(k, task);
            }
            if (!i.hasNext()) {
                break;
            }
            if (needsToSelectAgain) {
                selectAgain();
                selectedKeys = selector.selectedKeys();
                if (selectedKeys.isEmpty()) {
                    break;
                } else {
                    i = selectedKeys.iterator();
                }
            }
        }
    }

    /**
     * 使用优化数组实现处理 SelectionKey。
     * - 逻辑:
     *   - 遍历 selectedKeys.keys 数组,处理每个键。
     *   - 清空已处理键,检查 needsToSelectAgain。
     * - 设计理念:利用数组高效迭代,优化高并发性能。
     */
    private void processSelectedKeysOptimized() {
        for (int i = 0; i < selectedKeys.size; ++i) {
            final SelectionKey k = selectedKeys.keys[i];
            selectedKeys.keys[i] = null;
            final Object a = k.attachment();
            if (a instanceof AbstractNioChannel) {
                processSelectedKey(k, (AbstractNioChannel) a);
            } else {
                @SuppressWarnings("unchecked")
                NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
                processSelectedKey(k, task);
            }
            if (needsToSelectAgain) {
                selectedKeys.reset(i + 1);
                selectAgain();
                i = -1;
            }
        }
    }

    /**
     * 处理单个 SelectionKey 的 Channel 事件。
     * - 参数:k(SelectionKey),ch(AbstractNioChannel)。
     * - 逻辑:
     *   - 检查键有效性,无效则关闭 Channel。
     *   - 处理 OP_CONNECT、OP_WRITE、OP_READ/OP_ACCEPT 事件。
     * - 异常处理:捕获 CancelledKeyException,关闭 Channel。
     * - 设计理念:高效分发 I/O 事件,确保 Channel 状态一致。
     */
    private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {
        final AbstractNioChannel.NioUnsafe unsafe = ch.unsafe();
        if (!k.isValid()) {
            final EventLoop eventLoop;
            try {
                eventLoop = ch.eventLoop();
            } catch (Throwable ignored) {
                return;
            }
            if (eventLoop == this) {
                unsafe.close(unsafe.voidPromise());
            }
            return;
        }
        try {
            int readyOps = k.readyOps();
            if ((readyOps & SelectionKey.OP_CONNECT) != 0) {
                int ops = k.interestOps();
                ops &= ~SelectionKey.OP_CONNECT;
                k.interestOps(ops);
                unsafe.finishConnect();
            }
            if ((readyOps & SelectionKey.OP_WRITE) != 0) {
                unsafe.forceFlush();
            }
            if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {
                unsafe.read();
            }
        } catch (CancelledKeyException ignored) {
            unsafe.close(unsafe.voidPromise());
        }
    }

    /**
     * 处理 NioTask 的 SelectionKey 事件。
     * - 参数:k(SelectionKey),task(NioTask)。
     * - 逻辑:
     *   - 调用 task.channelReady() 处理事件。
     *   - 若异常,取消键并调用 channelUnregistered。
     *   - 确保无效键触发 channelUnregistered。
     * - 设计理念:支持自定义 NioTask,扩展事件处理。
     */
    private static void processSelectedKey(SelectionKey k, NioTask<SelectableChannel> task) {
        int state = 0;
        try {
            task.channelReady(k.channel(), k);
            state = 1;
        } catch (Exception e) {
            k.cancel();
            invokeChannelUnregistered(task, k, e);
            state = 2;
        } finally {
            switch (state) {
                case 0:
                    k.cancel();
                    invokeChannelUnregistered(task, k, null);
                    break;
                case 1:
                    if (!k.isValid()) {
                        invokeChannelUnregistered(task, k, null);
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 关闭所有注册的 Channel。
     * - 逻辑:
     *   - 调用 selectAgain() 清理键。
     *   - 遍历 selector.keys(),关闭 AbstractNioChannel 或调用 NioTask 的 channelUnregistered。
     * - 设计理念:确保事件循环关闭时清理所有资源。
     */
    private void closeAll() {
        selectAgain();
        Set<SelectionKey> keys = selector.keys();
        Collection<AbstractNioChannel> channels = new ArrayList<AbstractNioChannel>(keys.size());
        for (SelectionKey k : keys) {
            Object a = k.attachment();
            if (a instanceof AbstractNioChannel) {
                channels.add((AbstractNioChannel) a);
            } else {
                k.cancel();
                @SuppressWarnings("unchecked")
                NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
                invokeChannelUnregistered(task, k, null);
            }
        }
        for (AbstractNioChannel ch : channels) {
            ch.unsafe().close(ch.unsafe().void
项目管理 Agent:进度追踪与风险预警 Harness 我们先从LangChain的Agent定义说起:Agent是一个能感知环境、自主决策、调用工具、执行动作、迭代反思的智能实体。而「项目管理全自主Agent」,就是把Agent的核心能力和项目管理的五大过程组(启动、规划、执行、监控、收尾)深度结合,聚焦执行监控阶段的两个核心痛点:进度偏差自动化计算、风险信号自动化识别与预警的专门化Agent。全感知(Omnisensing):能从。 阅读详情

相关推荐

静态与动态LACP链路聚合:原理、配置与排错实战指南

链路聚合技术是提升网络带宽与可靠性的核心方案,通过将多个物理端口逻辑捆绑,实现带宽叠加与链路冗余。其原理基于IEEE 802.3ad标准,通过负载均衡算法将数据流分布到不同物理链路,既避免了数据包乱序,又提升了整体吞吐量。该技术的核心价值在于消除单端口瓶颈、提供毫秒级故障切换,并能简化网络拓扑管理。在企业服务器接入、数据中心互联及虚拟化平台等场景中,链路聚合已成为构建高可用网络的基础。实践中,动态LACP模式通过协议报文协商,能主动检测链路故障并防止配置错误导致的网络环路,相比静态聚合更为可靠。本文将深入解

weixin_31412781的博客 266

深入剖析Netty之NioEventLoop寻根究底

EventLoop在Netty中的作用至关重要,设计也非常的复杂,今天就跟随我一起将EventLoop拆解清楚!

1366

Rocfall安装包&安装教程

Rocfall 第一步:下载安装包 下载路径: 链接:https://pan.baidu.com/s/1Dzvxzv67dSPRi7f7ZT9EeA 提取码:o9pl 第二部:安装 安装包解压 选择part1进行解压 点击Setup.exe启动安装 生成Serial Number 替换启动程序 安装完毕 素材来源于网络(禁止用于商业仅用于完成毕业设计和研究使用) 谢谢! ...

cym的博客 8693

Netty NioEventLoop详解

Netty通过事件循环机制(EventLoop)处理IO事件和异步任务,简单来说,就是通过一个死循环,不断处理当前已发生的IO事件和待处理的异步任务。① NioEventLoop是一个基于JDK NIO的异步事件循环类,它负责处理一个Channel的所有事件在这个Channel的生命周期期间。② NioEventLoop的整个生命周期只会依赖于一个单一的线程来完成。

老码农的博客 2465

LCD、LED、OLED、Mini LED、Micro LED、全阵列LED、QLED、QD-OLED、QNED、AMOLED是什么意思?

LCD(液晶显示器,Liquid Crystal Display)定义:LCD 是一种利用液晶材料控制光线通过的显示技术,需依靠背光源(如冷阴极荧光灯 CCFL 或 LED)照亮液晶层以形成图像。技术原理:液晶分子在电场作用下改变排列,控制背光通过的强度和颜色。液晶本身不发光,需外部光源。特点:结构包括背光层、液晶层、彩色滤光片和偏光片。响应时间较慢,黑色表现因背光漏光而偏灰。LED(发光二极管显示,Light Emitting Diode)定义。

中国最威武的城市!武功军威-武威,铁骨铮铮! 3423

详解岭回归与L2正则化

最小二乘法存在不可逆和病态问题,导致解析解不可计算或不稳定,岭回归是一种有效的解决方法,以损失无偏性来换取稳定解, 本文介绍详细介绍了岭回归的基本原理,并从L2正则化角度来进行了解释。

Luoyingfeng的博客 1万+

NioEventLoop 解析

netty

qq_38148090的博客 481

【TC3xx芯片】TC3xx芯片电源管理系统PMS详解

本文主要介绍了TC3xx芯片的电源管理系统(PMS),重点探讨了供电模式选择、电源监控机制及电源管理模式。文章首先分析了4种供电模式及其硬件配置方式,详细说明了3.3V单电源供电模式的特点;其次阐述了Primary和Secondary两种电源监控机制,包括阈值配置和异常中断处理;最后重点讲解了CPU和系统的电源管理模式,特别对Standby模式及其进入/退出条件进行了详细说明。文章以软件开发视角解析了TC3xx芯片的电源管理功能,为ECU低功耗设计提供了技术参考。

redparrot2008的博客 1526

Netty核心源码解析(三)--NioEventLoop

首先,一个NioEventLoop聚合一个selector对象,这个selector对象就是JDK NIO中的selector对象(Netty可以配置选择是否对JDK 中的selector优化,优化主要是对selectionkeys集合优化,后续详细解释),通过代码可以看到,NioEventLoop的构造器里完成了selector的创建----(具体的selector创建Netty通过继承了jdk的SelectorProvider来实现的)至此,一次Eventloop循环就处理完了,总结一下---

冯宝宝 715

MIT Mini Cheetah--仿真流程

MIT Mini Cheetah–仿真 摘要 由于官方提供代码中,控制仿真环境中的猎豹机器人运动需要遥控器来控制。官方默认推荐使用logitech Gamepad F310游戏手柄:We use the Logitech F310 controller. There’s a switch in the back, which should be in the “X” position. The controller needs to reconnected if you change the switch

Galaxy_Robot的博客 5915

产品包装质检实战:基于YOLOv5的智能包装合格检测系统全流程指南

摘要: 针对产品包装质检效率低、漏检率高的问题,本文提出基于YOLOv5的智能检测系统。系统通过采集包装缺陷数据(破损、缺标、封装不良等),利用YOLOv5实现多类别缺陷识别(准确率≥95%),并开发Flask Web界面实现检测可视化与报告生成。实验表明,该系统在30帧/秒的产线速度下可稳定运行,显著提升质检效率。项目涵盖数据标注、模型训练、系统开发全流程,具有工业落地价值,适用于智能制造场景的自动化质检需求。(149字)

LXY_LOVE36的博客 92

Netty中NioEventLoop介绍

Netty中的核心类之一的:NioEventLoop类

小飞侠的博客 1187

YOLO26改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Backbone、SPPF、Neck、检测头等全方位改进

1️⃣ 什么!不知道如何改进模型⁉️ 本专栏已更新260多种不同的改进方法,所使用并改进的每一个模块均包含详细的模块分析、原理讲解、个人总结、多种改进方式以及完整的修改流程,所有改进100%可直接运行,性价比极高。2️⃣ 找不到合适的模块⁉️ 所有改进点均为近三年顶会,顶刊提出的先进算法,将其融入到中,并进行二次创新,新颖度高,创新度高,能够适应不同的任务场景。3️⃣ 不确定自己改进的步骤、结果是否正确⁉️ 订阅专栏即可进群享受模型训练、模型改进、论文写作、投稿选刊,从入门到论文的各种答疑内容,非常适合新手

Limiiiing的博客 6314

Netty源码NioEventLoop解析

因为异步任务处理是有超时时间的,所以 Netty 采取了定时检测的策略,每执行 64 个任务的时候就会检查一下是否超时,对性能的折中考虑,如果异步队列中有大量的短时间任务,每一次执行完都检测一次超时性能会有所降低。Netty的NioEventLoop并不是一个存粹的I/O线程,除了负责I/O的读写外(用于处理 Channel 生命周期内的所有I/O事件,如accept、connect、read、write等I/O事件),还负责处理系统任务和延迟任务(定时任务);

大鹏的博客 837

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Netty核心NioEventLoop源码解析

是Netty基于非阻塞式IO模型:通过非阻塞的IO模型,实现单个线程处理大量并发连接。事件驱动:基于事件驱动模型,管理和执行各种网络操作,例如:数据读写、连接管理、定时任务等,实现高效异步处理。内部包含一个事件队列,它会并按照收到的事件类型分发到对应的处理器上。IO多路复用:通过操作系统底层所提供的选择器(Selector)监听多个通道多个通道(即各个接入的连接),使得我们无需为每一个连接创建一个线程,不仅节约系统资源开销,还提升了系统的吞吐量。如下图所示,Netty对于EventLoop。

禅与计算机程序设计的艺术 583

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Netty源码解析-NioEventLoop

一:NioEventLoop的创建 NioEventLoop是由NioEventLoopGroup管理,所以创建操作要去NioEventLoopGroup找,如客户端代码中会先创建NioEventLoopGroup对象,从其构造函数入手,如你调用其无参构造器,一步步往下最终来到 public NioEventLoopGroup(int nThreads, Executor executor...

业精于勤荒于嬉 行成于思毁于随 644

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Netty技术全解析:NioEventLoop类源码分析与技术详解

NioEventLoop是Netty框架中负责处理网络IO事件和异步任务的核心组件。它通过单线程事件循环、IO多路复用、任务队列和定时任务调度等机制,实现了高效、可靠的网络事件处理。在Netty的网络编程模型中,NioEventLoop扮演着至关重要的角色。

码到三十五 1314

Netty 源码解析 ——— NioEventLoop 详解

文章目录1.NioEventLoop2.重要属性2.1taskQueue2.2tailTasks2.3scheduledTaskQueue2.4 SELECTOR_AUTO_REBUILD_THRESHOLD2.5selectNowSupplier2.6pendingTasksCallable静态代码块 原博文,点击这里 1.NioEventLoop 每个NioEventLoop里都有一个selector与TaskQueue,当我们在进行一些耗时的操作的时候,会产生阻塞,这时候我们就可以用到TaskQueu

weixin_42030357的博客 574

Netty源码解析(四) —— NioEventLoop处理io

NioEventLoop处理io的一些操作方法 io.netty.channel.nio.NioEventLoop#run /** * 启动服务 轮询selector */ @Override protected void run() { for (;;) { try { ...

fanday的博客 1980

Netty源码解析之NioEventLoop

阅读须知 Netty版本:4.1.14.Final 文章中使用/* */注释的方法会做深入分析 正文 Netty的EventLoop主要用于处理I/O操作,而NioEventLoop就是EventLoop的主要实现之一,它将Channel注册到Selector,因此在事件循环中可以对这些进行多路复用。我们首先来看NioEventLoop的层次结构: 我们首先来看它的构造方法: ...

0xZzzz的博客 1005

Netty源码简析之NIOEventLoop解析

举一个Netty服务端创建例子如下: EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(b...

Lisam Blog 534

Netty源码解析-NioEventLoop初始化

    作为Netty的核心组件之一,NioEventLoop负责处理netty中的各种事件,每个NioEventLoop上有一个selector负责轮询IO事件,有一个定时任务队列及普通任务队列负责处理注册到NioEventLoop上的非IO任务。而1组NioEventLoop右由一个NioEventLoopGroup负责管理,默认一个NioEventLoopGroup管理2倍CPU核数的Nio...

ybin__的博客 376

【Netty源码解析】NioEventLoop

上一篇博客【Netty源码学习】EventLoopGroup中我们介绍了EventLoopGroup,实际说来EventLoopGroup是EventLoop的一个集合,EventLoop是一个单线程的线程池,其接口和类实现关系如下:接下来我们主要介绍实现类NioEventLoop中实现的操作,通过NioEventLoop的继承关系图我们可以看到,其就是一个单线程的线程池。首先我们看NioEven

井底之蛙 2625

Netty源码解析-NioEventLoop(二)

Netty源码4.1.22 继前一篇,下面该分析processSelectedKeys() processSelectedKeys()处理IO事件 private void processSelectedKeys() { if (selectedKeys != null) { processSelectedKeysOptimized(); ...

业精于勤荒于嬉 行成于思毁于随 333

netty源码解析01-NioEventLoop详解01

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Ma

qq_36707152的博客 457

Netty(八)源码解析 之 NioEventLoopGroup和NioEventLoop源码分析、NioEventLoop绑定线程的流程分析

NioEventLoop源码 1. NioEventLoopGroup的构造分析 EventLoopGroup parentGroup = new NioEventLoopGroup(); EventLoopGroup childGroup = new NioEventLoopGroup(); 我们先从NioEventLoopGroup开始,NioEventLoopGroup根据名字就能知道里面肯定包含了很多NioEventLoop 先看下NioEventLoop继承体系: 关键点:NioEventLo

语雀同名:犬豪 yuque.com/qhao 2071
上一篇: Netty是如何解决epoll CPU占用100%问题的
下一篇: Effective Java笔记:静态工厂方法代替构造器
Jooou
博客等级 码龄9年 226粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值