netty 服务端启动流程源码详解( 五 )

归根到底,默认的 SelectorProvider 应该是 jdk nio 的 DefaultSelectorProvider 。
实际上,还是根据初始化 ServerSocketChannel:
public NioServerSocketChannel(ServerSocketChannel channel) {    super(null, channel, SelectionKey.OP_ACCEPT);    config = new NioServerSocketChannelConfig(this, javaChannel().socket());}可以看到,这里默认注册监听了 SelectionKey.OP_ACCEPT 事件 。
其中 SelectionKey 只有 4 种:
public static final int OP_ACCEPT = 1 << 4;public static final int OP_CONNECT = 1 << 3;public static final int OP_WRITE = 1 << 2;public static final int OP_READ = 1 << 0;NioserverSocketChannel 注册注册的源码比较多,看得人云里雾里的 。
可以理解,就是首先注册自己感兴趣的事件,发生的时候通知你即可 。
注册的方法如下我们主要看 NioEventLoop 即可,这个类继承自 SingleThreadEventLoop 类 。
实现了 SingleThreadEventExecutor 类的 run 方法,如下:
@Overrideprotected void run() {    for (;;) {        try {            switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {                case SelectStrategy.CONTINUE:                    continue;                case SelectStrategy.SELECT:                    select(wakenUp.getAndSet(false));                    if (wakenUp.get()) {                        selector.wakeup();                    }                    // fall through                default:            }            // 省略            processSelectedKeys();            // 省略        } catch (Throwable t) {            handleLoopException(t);        }        // Always handle shutdown even if the loop processing threw an exception.        // 省略    }}我们只看核心的部分,这里实际上就是一个死循环,注册的部分核心如下:
public void register(final SelectableChannel ch, final int interestOps, final NioTask<?> task) {    // 省略    ch.register(selector, interestOps, task);    // 省略}在 AbstractSelectableChannel 中的实现如下:
public final SelectionKey register(Selector sel, int ops,                                   Object att)    throws ClosedChannelException{    synchronized (regLock) {        // 省略        SelectionKey k = findKey(sel);        if (k != null) {            k.interestOps(ops);            k.attach(att);        }        if (k == null) {            // New registration            synchronized (keyLock) {                if (!isOpen())                    throw new ClosedChannelException();                k = ((AbstractSelector)sel).register(this, ops, att);                addKey(k);            }        }        return k;    }}


推荐阅读