open
方法,后者会调用java.nio.channels.spi.SelectorProvider
来创建一个新的Selector。close
方法为止。一个selectable Channel与一个Selector之间的注册关系是用一个SelectionKey对象标表示的。一个Selector会维护三种key的集合:
select
、selectNow
或selectLong
,下同)中被添加到集合,或者被更新准备状态的。
.调用keys()
可返回这个key set。selectedKeys()
可返回这个集合。key set是selected-key set 和 cancelled-key set的并集。 三种集合在Selector新创建时都是空的。
register
方法来注册一个Channel时,作为副作用,一个key就会被加入到Selector的key set。在selection操作中,被取消的key都会被从key set中移除。key set本身是外界不可修改的。cancel
操作后,这个key就被取消,并且被添加到cancelled-key set中。取消一个key会导致在下一轮selection操作中,该
key的Channel被注销,并且被从Selector的所有key集合中被移除。key
方法,或者调用集合的迭代器的remove
方法。要删除该集合的所有key,可直接调用clear
方法。
selected-key set是不能被外界直接向其中添加key的。一个Selection操作指调用select
、selectNow
或selectLong
。
(注释太长了,我简短地写)
个人试验后发现,一个readable的selectionKey,一定要调用它的通道的read方法,把内容读完才行。如果不读取,或者由于ByteBuffer太小没读完,则下一次该key仍然会处于可读取状态。
根据试验,select
方法会阻塞,线程对每一个通道询问操作系统是否有事件触发,直到有事件触发。之后对于每一个SelectedKey,在一个系统中串行执行(也就是说,如果某一个操作太慢,会拖延之后的key执行时间)。