SelectionKey类
简介:
表示 SelectableChannel 在 Selector 中的注册的标记。
每次向选择器注册通道时就会创建一个选择键。通过调用某个键的 cancel 方法、关闭其通道,或者通过关闭其选择器来取消 该键之前,它一直保持有效。取消某个键不会立即从其选择器中移除它;相反,会将该键添加到选择器的已取消键集,以便在下一次进行选择操作时移除它。可通过调用某个键的 isValid 方法来测试其有效性。
选择键包含两个表示为整数值的操作集。操作集的每一位都表示该键的通道所支持的一类可选择操作。
interest 集合 确定了下一次调用某个选择器的选择方法时,将测试哪类操作的准备就绪信息。创建该键时使用给定的值初始化 interest 集合;之后可通过 interestOps(int) 方法对其进行更改。
ready 集合 标识了这样一类操作,即某个键的选择器检测到该键的通道已为此类操作准备就绪。创建该键时 ready 集合被初始化为零;可以在之后的选择操作中通过选择器对其进行更新,但不能直接更新它。
选择键的 ready 集合指示,其通道对某个操作类别已准备就绪,该指示只是一个提示,并不保证线程可执行此类别中的操作而不导致被阻塞。ready 集合很可能一完成选择操作就是准确的。ready 集合可能由于外部事件和在相应通道上调用的 I/O 操作而变得不准确。
此类定义了所有已知的操作集位 (operation-set bit),但是给定的通道具体支持哪些位则取决于该通道的类型。SelectableChannel 的每个子类都定义了 validOps() 方法,该方法返回的集合恰好标识该通道支持的操作。试图设置或测试某个键的通道所不支持的操作集位将导致抛出相应的运行时异常。
通常必须将某个特定于应用程序的数据与某个选择键相关联,例如表示高级协议状态的对象和为了实现该协议而处理准备就绪通知的对象。因此,选择键支持将单个任意对象附加 到某个键的操作。可通过 attach 方法附加对象,然后通过 attachment 方法获取该对象。
多个并发线程可安全地使用选择键。一般情况下,读取和写入 interest 集合的操作将与选择器的某些操作保持同步。具体如何执行该同步与实现有关:在一般实现中,如果正在进行某个选择操作,那么读取或写入 interest 集合可能会无限期地阻塞;在高性能的实现中,可能只会暂时阻塞。无论在哪种情况下,选择操作将始终使用该操作开始时当前的 interest 集合值。
主要方法
attach
public final Object attach(Object ob)将给定的对象附加到此键。
之后可通过 attachment 方法获取已附加的对象。一次只能附加一个对象;调用此方法会导致丢弃所有以前的附加对象。通过附加 null 可丢弃当前的附加对象。
参数:
ob - 要附加的对象,可以为 null
返回:
先前已附加的对象(如果有),否则返回 null
attachment
public final Object attachment()获取当前的附加对象。
返回:
当前已附加到此键的对象,如果没有附加对象,则返回 null
channel
public abstract SelectableChannel channel()返回为之创建此键的通道。即使已取消该键,此方法仍继续返回通道。
返回:
此键的通道
selector
public abstract Selector selector()返回为此选择器创建的键。即使已取消该键后,此方法仍将继续返回选择器。
返回:
此键的选择器
interestOps
public abstract SelectionKey interestOps(int ops)将此键的 interest 集合设置为给定值。
可在任意时间调用此方法。是否受阻塞,以及阻塞时间长短都是与实现相关的。
参数:
ops - 新的 interest 集合
返回:
此选择键
抛出:
IllegalArgumentException - 如果集合中的某个位与此键的通道所支持的某个操作不对应,也就是说,如果 set & ~(channel().validOps()) != 0
CancelledKeyException - 如果已取消此键
readyOps
public abstract int readyOps()获取此键的 ready 操作集合。
可保证返回的集合仅包含对于此键的通道而言有效的操作位。
返回:
此键的 ready 操作集合
抛出:
CancelledKeyException - 如果已取消此键
isReadable
public final boolean isReadable()测试此键的通道是否已准备好进行读取。
调用此方法的形式为 k.isReadable() ,该调用与以下调用的作用完全相同:
k.readyOps() & OP_READ != 0如果此键的通道不支持读取操作,则此方法始终返回 false。
返回:
当且仅当 readyOps() & OP_READ 为非零值时才返回 true
抛出:
CancelledKeyException - 如果已取消此键
isWritable
public final boolean isWritable()测试此键的通道是否已准备好进行写入。
调用此方法的形式为 k.isWritable() ,该调用与以下调用的作用完全相同:
k.readyOps() & OP_WRITE != 0如果此键的通道不支持写入操作,则此方法始终返回 false。
返回:
当且仅当 readyOps() & OP_WRITE 为非零值时才返回 true
抛出:
CancelledKeyException - 如果已取消此键
isConnectable
public final boolean isConnectable()测试此键的通道是否已完成其套接字连接操作。
调用此方法的形式为 k.isConnectable() ,该调用与以下调用的作用完全相同:
k.readyOps() & OP_CONNECT != 0如果此键的通道不支持套接字连接操作,则此方法始终返回 false。
返回:
当且仅当 readyOps() & OP_CONNECT 为非零值时才返回 true
抛出:
CancelledKeyException - 如果已取消此键
isAcceptable
public final boolean isAcceptable()测试此键的通道是否已准备好接受新的套接字连接。
调用此方法的形式为 k.isAcceptable() 形式,该调用与以下调用的作用完全相同:
k.readyOps() & OP_ACCEPT != 0如果此键的通道不支持套接字接受操作,则此方法始终返回 false。
返回:
当且仅当 readyOps() & OP_ACCEPT 为非零值时才返回 true
抛出:
CancelledKeyException - 如果已取消此键