关键代码:NioEventLoop => **final SelectorTuple selectorTuple = openSelector();**

    1. NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
    2. SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler,
    3. EventLoopTaskQueueFactory queueFactory) {
    4. // parent:this => NioEventLoopGroup
    5. // selectorProvider:SelectorProvider 默认为 SelectorProvider.provider(),该方法可以打开一个 selector 或者 ServerSocketChannel
    6. // strategy:selectStrategyFactory 默认选择策略工厂
    7. // rejectedExecutionHandler:RejectedExecutionHandler 线程拒绝策略,默认为 抛异常
    8. super(parent, executor, false, newTaskQueue(queueFactory), newTaskQueue(queueFactory),
    9. rejectedExecutionHandler);
    10. if (selectorProvider == null) {
    11. throw new NullPointerException("selectorProvider");
    12. }
    13. if (strategy == null) {
    14. throw new NullPointerException("selectStrategy");
    15. }
    16. // provider = SelectorProvider.provider()
    17. provider = selectorProvider;
    18. // ★ 开始创建 selector
    19. // ★ SelectorTuple = [selector = SelectedSelectionKeySetSelector 做了一层包装的 Selector, unwrappedSelector = 替换了 HashSet 的原生 selector]
    20. final SelectorTuple selectorTuple = openSelector();
    21. // ★ selector = SelectedSelectionKeySetSelector 做了一层包装的 Selector
    22. selector = selectorTuple.selector;
    23. // ★ unwrappedSelector = 替换了 HashSet 的原生 selector
    24. unwrappedSelector = selectorTuple.unwrappedSelector;
    25. // selectStrategyFactory 默认选择策略工厂
    26. selectStrategy = strategy;
    27. }

    利用反射:**sun.nio.ch.SelectorImpl,将 SelectorImpl 中的 HashSet keys,与 Set publicKeys 属性,替换为** Netty 自己实现的 Set(SelectedSelectionKeySet)

    1. private SelectorTuple openSelector() {
    2. final Selector unwrappedSelector;
    3. try {
    4. unwrappedSelector = provider.openSelector();
    5. } catch (IOException e) {
    6. throw new ChannelException("failed to open a new selector", e);
    7. }
    8. if (DISABLE_KEY_SET_OPTIMIZATION) {
    9. return new SelectorTuple(unwrappedSelector);
    10. }
    11. Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
    12. @Override
    13. public Object run() {
    14. try {
    15. return Class.forName(
    16. "sun.nio.ch.SelectorImpl",
    17. false,
    18. PlatformDependent.getSystemClassLoader());
    19. } catch (Throwable cause) {
    20. return cause;
    21. }
    22. }
    23. });
    24. if (!(maybeSelectorImplClass instanceof Class) ||
    25. // isAssignableFrom() 方法是从继承的角度来判断,instanceof 关键字是从实例继承的角度来判断
    26. // isAssignableFrom() 方法是判断是否是某个类的父类,instanceof 关键字是判断是否是某个类的子类
    27. // 使用方法:父类.class.isAssignableFrom(子类.class),子类实例 instanceof 父类类型
    28. // ensure the current selector implementation is what we can instrument.
    29. !((Class<?>) maybeSelectorImplClass).isAssignableFrom(unwrappedSelector.getClass())) {
    30. if (maybeSelectorImplClass instanceof Throwable) {
    31. Throwable t = (Throwable) maybeSelectorImplClass;
    32. logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, t);
    33. }
    34. return new SelectorTuple(unwrappedSelector);
    35. }
    36. final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
    37. // Netty 自定义的 Set 集合
    38. final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
    39. Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
    40. @Override
    41. public Object run() {
    42. try {
    43. // selectedKeysField = HashSet<SelectionKey>
    44. Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
    45. // publicSelectedKeysField = HashSet<SelectionKey>
    46. Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
    47. // 版本判断(可忽略)
    48. if (PlatformDependent.javaVersion() >= 9 && PlatformDependent.hasUnsafe()) {
    49. // Let us try to use sun.misc.Unsafe to replace the SelectionKeySet.
    50. // This allows us to also do this in Java9+ without any extra flags.
    51. long selectedKeysFieldOffset = PlatformDependent.objectFieldOffset(selectedKeysField);
    52. long publicSelectedKeysFieldOffset =
    53. PlatformDependent.objectFieldOffset(publicSelectedKeysField);
    54. if (selectedKeysFieldOffset != -1 && publicSelectedKeysFieldOffset != -1) {
    55. PlatformDependent.putObject(
    56. unwrappedSelector, selectedKeysFieldOffset, selectedKeySet);
    57. PlatformDependent.putObject(
    58. unwrappedSelector, publicSelectedKeysFieldOffset, selectedKeySet);
    59. return null;
    60. }
    61. // We could not retrieve the offset, lets try reflection as last-resort.
    62. }
    63. // 反射设置可对私有属性赋值
    64. Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField, true);
    65. if (cause != null) {
    66. return cause;
    67. }
    68. // 反射设置可对私有属性赋值
    69. cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField, true);
    70. if (cause != null) {
    71. return cause;
    72. }
    73. // ★★★ 替换了 selectedKeys 原来的 HashSet<SelectionKey> 为 SelectedSelectionKeySet
    74. selectedKeysField.set(unwrappedSelector, selectedKeySet);
    75. // ★★★ 替换了 publicSelectedKeys 原来的 HashSet<SelectionKey> 为 SelectedSelectionKeySet
    76. publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
    77. return null;
    78. } catch (NoSuchFieldException e) {
    79. return e;
    80. } catch (IllegalAccessException e) {
    81. return e;
    82. }
    83. }
    84. });
    85. // 异常判断(可忽略)
    86. if (maybeException instanceof Exception) {
    87. selectedKeys = null;
    88. Exception e = (Exception) maybeException;
    89. logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, e);
    90. return new SelectorTuple(unwrappedSelector);
    91. }
    92. // 保存
    93. selectedKeys = selectedKeySet;
    94. logger.trace("instrumented a special java.util.Set into: {}", unwrappedSelector);
    95. // unwrappedSelector 已经替换过底层实现的 selector
    96. return new SelectorTuple(unwrappedSelector,
    97. // 包装了一下 selector,重写了某些方法
    98. new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet));
    99. }