Nio(seletor为什么要处理完的key要手动清除(remove))
这里我们要先有一个逻辑模型,
3、我们的key
流程:
第一步:首先我们是启动我们服务器端嘛,然后这里有有个服务器通道了(模拟服务器),我们将这个放到seletor里面(这个ssc还监听了accept这个事件,管理的是serversoketchannel)
第二步、他向下运行到selector.select()方法阻塞。
第三步、!!!这时我们客户端去启动,那么selector.select就会接收到连接请求事件,线程又运行,代码往下执行建立一个新的集合(selector的selectedkeys)里面放的是我们就收到的事件。什么事件嘛(就是我们上面的selector里面监听到的事件啊(ssckey@xxx accept))!!!!java就将上面的拷贝放到这个集合中。
注意这个selector的selectedKeys只会往里面加内容,也就是加管理通道事件的key咯,但是他不会去主动的删除key(selector在事件发生后,向这个集合加key,但不会主动的去删除key)
第四步、迭代器循环拿出集合的key打印咯
第五步、对这个key进行处理,就去判断进入分支处理事件,连接之后(也就是处理之后,他就会将这个事件给删除也就是删除accept(但是这个key还在这个集合里))
第六步、再往下运行这个客户端连接通道channel,将这个sc注册到selector了加入一个新的key(sckey,事件是read。Sc这个通道)
第七步、!!!!又开始引入下一个循环了,又将我们的sckey复制到集合中(selector的selectedKeys),
但是注意这里我们这里的遍历集合我们打印的key确是我们第一次的事件已经被处理的ssckey。他在建立连接时出错,他的连接事件已经被处理了(accept已经没了),所以这个accept返回数据的是null(accept在非阻塞模式下,其中返回的是null),所以我们再去处理报空指针咯
!!!总结:我们再处理完我们的事件后,我们的key应该删除(从集合(selector的selectedkeys)里面删除(迭代器删除.remove))。所以我们前面才需要用迭代器模式去遍历这个集合啊666