这其实是Stackoverflow上的一个问题。Netty的核心开发者Norman Maurer给出了答案:
Netty的epoll transport使用了边缘触发,而java的NIO库使用了水平触发。而且Netty的epoll transport支持了java nio没有支持的配置选项,例如TCP_CORK、SO_REUSEPORT等等。
epoll的边缘触发(Edge Triggered,ET)和水平触发(Level Triggered,LT)
对于水平触发LT来说,会持续通知直到事件处理完毕。而边缘触发ET只会通知一次,不管事件是否处理完毕。
epoll_wait的相关工作流程:
- 当内核监控的fd产生用户关注的事件,内核将fd(epi)节点信息添加进就绪队列。
- 内核发现就绪队列有数据,唤醒进程工作。
- 内核先将fd从就绪队列删除。
- 然后将fd对应就绪事件信息从内核空间拷贝到工作空间。
- 事件数据拷贝完成之后,内核检查事件模式是lt还是et。如果不是et,重新将fd信息添加回就绪队列,下次重新触发epoll_wait。
参考
nio - Why native epoll support is introduced in Netty? - Stack Overflow