title | date | categories | tags | description | |||
---|---|---|---|---|---|---|---|
SelectionKey |
2020-01-20 |
|
|
|
SelectionKey 用于表示 Channel 和 Selector 的一种注册关系。其实在Selector的角度来看,一个 SelectionKey 来代表一个Channel,以及这个Channel它关注什么事件。
也可以理解为:每次 Channel 一注册到 Selector,就产生一个SelectionKey对象(相当于注册的副作用),然后,这个SelectionKey 还携带了 Channel 及 Selector相关信息。
这样, Selector 就不会维护 Channel 的集合,只要维护 SelectionbKey 的集合就好了。
我们可以想象,SelectionKey中维护了哪些东东:
伪代码
public class SelectionKey {
// 应该至少维护下面三个变量
// 哪个 Channel 注册到了哪个Selector 上, 以及这个channel它感兴趣的操作是什么
Channel channel;
Selector selector;
int interestOperation;
}
我们查看 SelectionKey 的源码,可以看到里面还有一些常量,代表各种类型的事件:
OP_READ 1 Operation-set bit for read operations.
OP_WRITE 4 Operation-set bit for write operations.
OP_CONNECT 8 Operation-set bit for socket-connect operations.
OP_ACCEPT 16 Operation-set bit for socket-accept operations.
在调用register方法的时候,第二个参数即传递感兴趣的事件类型
socketChannel.register(selector, SelectionKey.OP_READ);
register之后会返回一个 SelectionKey, 这个SelectionKey 会加入到Selector 的 keys集合中进行管理。
selector()
获取到注册的selector
channel()
获取与该SelectionKey对应的channel
attachment()
register(register的三个参数的方法)的时候设置的关联对象, 可以通过这个方法拿到
public final SelectionKey register(Selector sel, int ops,
Object att)
interestOps()
拿到Channel感兴趣的事件
interestOps(int x)
重新设置监听的感兴趣事件
isAcceptable()
Tests whether this key's channel is ready to accept a new socket connection.
isReadable()
Tests whether this key's channel is ready for reading.
isWriteable()
Tests whether this key's channel is ready for writing.