谈谈java selector的机制(三)

2014-11-24 07:40:06 · 作者: · 浏览: 3
起连接,上面的方法返回
再次注销cancelledKeys【已取消的键的集合】中的key
EPollSelectorImpl.updateSelectedKeys
如果selectedKeys【已选择的键的集合】包含该键
ServerSocketChannelImpl.translateReadyOps
将PollArrayWrapper.POLLIN转化为SelectionKey.OP_ACCEPT
更新readyOps
判断老的readyOps是否和新的readyOps,如果不一致事件数+1
如果selectedKeys【已选择的键的集合】不包含该键
ServerSocketChannelImpl.translateReadyOps
将该键填入selectedKeys
事件数+1
如果事件数>1,遍历事件对应的key,开始相应处理。。。
Java NIO这本书提到“一旦键 被放置于选择器的已选择的键的集合中,它的 ready 集合(即readyOps)将是累积的。比特位只会被设置,不会被 清理”,实际并非如此,就我的理解和观察的结果,readyOps并不会积累而是每次更新,不明白为什么作者会这么说???,无论如何对整体的程序理解不会有影响
java使用epoll默认会使用水平触发,即如果有事件发生,如果你不处理,那么下次还会触发
但经过java 中EPollSelectorImpl实现之后有了小小的变化,如果某个事件发生,你不做任何处理,那么下次调用select的时候,虽然底层epoll仍然会返回事件,但上面的代码会判断本次事件和上次事件是否一致,如果是一样,java认为没有事件发生,如果要做到一致,必须将selectedKeys中的key删掉,否则会有差别,所以请注意selectedKeys删除的重要性!否则会死循环!
上面已经解释了ServerSocketChannel的注册,以及select过程,代码样例还有SocketChannel的注册和select,其实和前面很雷同就不再赘述了


摘自 pwlazy的专栏