参考: https://www.jianshu.com/p/6bdee8cfee9
- 触发的方式有两种
a) 水平触发(level-triggered,也被称为条件触发)LT: 只要满足条件,就触发一个事件(只要有数据没有被获取,内核就不断通知你)
b) 边缘触发(edge-triggered)ET: 每当状态变化时,触发一个事件。 - 水平触发:
a) 对于读操作 :只要内核缓冲区内容不为空,LT模式返回读就绪。
b) 对于写操作 :只要内核缓冲区还不满,LT模式会返回写就绪。 - Java NIO属于水平触发,即条件触发
由此我们对问题进行分析:
-
为什么不调用ServerSocketChannel.accept() 就会一直触发accept ready 事件?
因为java NIO 事件触发属于水平触发 ,所以如果我们不清理掉"accept"内容,就会一直触发 accpet ready 事件 -
为什么我的代码会一直触发 writer ready事件?
因为内核缓冲区还不满,所以一直写就绪 -
为什么别人的代码,在SocketChannel上不注册writer ready、connect ready事件?
因为注册writer ready没有必要,且只要内核缓冲区还不满就会一直写就绪。
而后面我们发现,connect ready事件是针对客户端而言,相当于服务器端accpet ready事件,也就是说通过ServerSocketChannel#accept()获得获取的SocketChannel对象是不需要注册 connect ready事件。