张龙netty学习笔记 P41 nio网络编程

2019-05-25 09:12:06 浏览数 (3)

Selector

1.1 开启与关闭

  • 要创建一个Selector,可以通过调用它的open方法,后者会调用java.nio.channels.spi.SelectorProvider来创建一个新的Selector
  • Selector会一直保持开启,直到调用close方法为止。

1.2 维持三种selectionKey的集合

一个selectable Channel与一个Selector之间的注册关系是用一个SelectionKey对象标表示的。一个Selector会维护三种key的集合:

  1. key set。一个Selector上会注册有多个Channel,而key set就包含了所有在这个Selector上含有通道注册关系的key。这些key都是在之前的selection操作(指调用selectselectNowselectLong,下同)中被添加到集合,或者被更新准备状态的。 .调用keys()可返回这个key set。
  2. selected-key set。这个集合里每一个key的通道,都是被检测到准备好至少一种该通道所感兴趣的事件。 调用selectedKeys()可返回这个集合。
  3. cancelled-key set。包含的key都是那些key被取消而Channel还没被注销的。 这个集合不能直接被外界访问。

key set是selected-key set 和 cancelled-key set的并集。 三种集合在Selector新创建时都是空的。

1.3 三种集合中selectionKey的添加与删除

  1. 关于key set。当通过调用Channelregister方法来注册一个Channel时,作为副作用,一个key就会被加入到Selector的key set。在selection操作中,被取消的key都会被从key set中移除。key set本身是外界不可修改的。
  2. 关于cancelled-key set。当Channel关闭或调用SelectionKeycancel操作后,这个key就被取消,并且被添加到cancelled-key set中。取消一个key会导致在下一轮selection操作中,该 key的Channel被注销,并且被从Selector的所有key集合中被移除。
  3. 关于selected-key set。要删除某个key,可以直接调用集合的key方法,或者调用集合的迭代器的remove方法。要删除该集合的所有key,可直接调用clear方法。 selected-key set是不能被外界直接向其中添加key的。

1.4 Selection操作

一个Selection操作指调用selectselectNowselectLong。 (注释太长了,我简短地写)

  1. 把 cancelled-key set中每个key都移除,把它们的Channel都注销。这会把 cancelled-key set清空。
  2. 为剩下的每一个key,询问操作系统是否有该key感兴趣的事件发生。

个人理解

个人试验后发现,一个readable的selectionKey,一定要调用它的通道的read方法,把内容读完才行。如果不读取,或者由于ByteBuffer太小没读完,则下一次该key仍然会处于可读取状态。

根据试验,select方法会阻塞,线程对每一个通道询问操作系统是否有事件触发,直到有事件触发。之后对于每一个SelectedKey,在一个系统中串行执行(也就是说,如果某一个操作太慢,会拖延之后的key执行时间)。

0 人点赞