Nio2Endpoint 中没有 Poller(Selector)。
    这是为什么呢?因为在异步 I/O 模式下,Selector 的工作交给内核来做了。

    image.png

    在异步 I/O 模型里,内核做了很多事情,它把数据准备好,并拷贝到用户空间,再通知应用程序去处理,也就是调用应用程序注册的回调函数。Java 在操作系统 异步 IO API 的基础上进行了封装,提供了 Java NIO.2 API,而 Tomcat 的异步 I/O 模型就是基于 Java NIO.2 实现的。

    由于 NIO 和 NIO.2 的 API 接口和使用方法完全不同,因此如果系统已经支持同步 I/O,要再支持异步 I/O,那么改动是比较大的,甚至不得不重新设计组件之间的接口。

    Tomcat 通过充分的抽象,比如 SocketWrapper 对 Channel 的封装,再加上 Http11Processor 的两次 read 调用,巧妙地解决了这个问题,使得协议处理器 Http11Processor 和 I/O 通信处理器 Endpoint 之间的接口保持不变。