SelectionKey源码解析
转载自: http://blog.csdn.net/robinjwong/article/details/41792623
SelectionKey表示监听的事件。将channel注册到selector上时,需要声明SelectionKey,以此声明监听事件。(这样Selector才知道需要记录什么数据)
注:
句柄:可以认为是对象身份的唯一id,标识应用程序中的不同对象和同类中的不同的实例。句柄不是指针,程序不能利用句柄来直接阅读文件中的信息。
解析jdk源码:
//表示SelectableChannel 在Selector中的注册的标记/句柄 public abstract class SelectionKey { //构造该类的一个实例。 protected SelectionKey() { } //返回创建此键的通道。即使在键被取消后,该方法将仍然返回通道。 public abstract SelectableChannel channel(); //返回创建此键的选择器。该方法将在取消键后,继续返回选择器。 public abstract Selector selector(); //说明此键是否有效。key在创建时是有效的,直到它被取消,其通道关闭,或其选择器关闭。 public abstract boolean isValid(); /** *请求用选择器注册这个密钥的通道。 *被取消。在返回时,key将无效并将一直存在。 *添加到选择器的取消键集中。 *在下一次选择操作中所有选择器的键集将被移除。 *如果这个键已经被取消了,那么调用这个方法就没有影响。一旦取消,key将永远无效。 *这个方法可以在任何时候调用。它同步选择器的取消键集,因此在调用时可能会阻塞。 *与取消或选择有关的操作同时进行。 */ public abstract void cancel(); /**检索此键的兴趣集。(既SelectionKey选择的4个监听key) *保证返回的集合只包含对该密钥通道操作有效的位。这个方法可以在任何时候调用。 *不管它是否阻塞,以及实现依赖的时间长短。 */ public abstract int interestOps(); /** *将此键的兴趣设置为给定值。这个方法可以在任何时候调用。 *不管它是否阻塞,以及实现依赖的时间长短。 */ public abstract SelectionKey interestOps(int ops); //检索此键的已操作集。 public abstract int readyOps(); /** *操作设置位用于读取操作。 1不进行左移 *假设一个选择键的兴趣集包含OP_READ。如果选择器 *检测到对应的通道已准备好读取,已经到达。 *结束流,已被远程关闭以供进一步阅读或使用。 *在未处理的情况下,它将添加OP_READ到关键字。 *已经操作的集合,并将键添加到它的选择键。 */ public static final int OP_READ = 1 << 0; //写操作 1左移2位--4 public static final int OP_WRITE = 1 << 2; //客户端请求连接服务端 1左移3位--8 public static final int OP_CONNECT = 1 << 3; //服务端请求连接客户端 1左移4位--16 public static final int OP_ACCEPT = 1 << 4; /** *测试此键的通道是否可以读取。 *如不支持读取操作,则返回false。 */ public final boolean isReadable() { return (readyOps() & OP_READ) != 0; } //测试此键的通道是否可以写入。 public final boolean isWritable() { return (readyOps() & OP_WRITE) != 0; } //测试此键的通道是否可以连接。 public final boolean isConnectable() { return (readyOps() & OP_CONNECT) != 0; } //测试此键的通道是否可以连接。 public final boolean isAcceptable() { return (readyOps() & OP_ACCEPT) != 0; } private volatile Object attachment = null; private static final AtomicReferenceFieldUpdater<SelectionKey,Object> attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater( SelectionKey.class, Object.class, "attachment" ); //将给定对象连接到此键。 public final Object attach(Object ob) { return attachmentUpdater.getAndSet(this, ob); } //检索当前的附件。 public final Object attachment() { return attachment; } }