API笔记之java.nio.channels.SelectionKey
- import java.nio.channels.SelectableChannel;
- import java.nio.channels.Selector;
- import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
- /**
- * A token representing the registration of a {@link SelectableChannel} with a
- * {@link Selector}.
- *
- * A token representing the registration of a SelectableChannel with a Selector.
- * 一个SelectoableChannel在Selector中注册之后就产生一个SelectionKey对象,表示我们对这个SelectoableChannel的什么事件感兴趣,当然
- * SelectionKey的interestOps是我们自己传进去的, 我们调用selector的selectedKey方法会返回被选中的SelectionKey集,通过这个key判断
- * 什么事件,然后通过channel()方法进行io操作
- */
- public abstract class SelectionKey {
- /**
- * 四种事件用一个int(intrestOps)变量表示(其实byte也够了?)
- * bits: [0|1] [0|1] [0|1] [0|1]
- * means: accept connect write read
- * 想要哪几种事件,就对这些事件的值进行或运算,得出的就是intrestOps
- *比如 interestOps = 2(0010),该key会被选中, 事件是write, 主线逻辑拿得到这个key对应的channel可以进行写操作
- */
- /**
- * 当selector发现:
- * 1.channel有数据可读
- * 2.channel has been remotely shut down for further reading(不能100%确定其意思,猜测是channel的读通道关闭)
- * 3.channel has an error pending,有错误待处理?
- * 时, selector就会把该key加到selected key set中
- */
- public static final int OP_READ = 1 << 0;
- /**
- *这三个和上面差不多
- */
- public static final int OP_WRITE = 1 << 2;
- public static final int OP_CONNECT = 1 << 3; // 这个只有SocketChannel才有
- public static final int OP_ACCEPT = 1 << 4; // 这个只有ServerSocketChannel才有
- /**
- * 不给外部new实例, 在SelectionKeyImpl中会开放这个构造方法给包内的lei使用
- */
- protected SelectionKey() { }
- /**
- * Returns the channel for which this key was created. This method will
- * continue to return the channel even after the key is cancelled.
- */
- public abstract SelectableChannel channel();
- /**
- * Returns the selector for which this key was created. This method will
- * continue to return the selector even after the key is cancelled.
- */
- public abstract Selector selector();
- /**
- * Tells whether or not this key is valid.
- *
- * 当key被创建开始就是valid的,直到以下情况发生:
- * 1.cancel()方法被调用
- * 2.它对应的channel的被close
- * 3.它对应的selector被close
- */
- public abstract boolean isValid();
- /**
- * Requests that the registration of this key's channel with its selector
- * be cancelled.
- * 被调用后,该key就是invalid的了,会被加到对应的selector的cancelled key set中,当selector的下一次选择操作时,
- * 该key就会被移除(selector的三种key set)
- */
- public abstract void cancel();
- /**
- * Retrieves this key's interest set.
- */
- public abstract int interestOps();
- /**
- * Sets this key's interest set to the given value.
- */
- public abstract SelectionKey interestOps(int ops);
- /**
- * Retrieves this key's ready-operation set.
- */
- public abstract int readyOps();
- /**
- * Tests whether this key's channel is ready for reading.
- */
- public final boolean isReadable() {
- return (readyOps() & OP_READ) != 0;
- }
- /**
- * Tests whether this key's channel is ready for writing.
- */
- public final boolean isWritable() {
- return (readyOps() & OP_WRITE) != 0;
- }
- /**
- * Tests whether this key's channel has either finished, or failed to
- * finish, its socket-connection operation.
- */
- public final boolean isConnectable() {
- return (readyOps() & OP_CONNECT) != 0;
- }
- /**
- * Tests whether this key's channel is ready to accept a new socket
- * connection.
- */
- 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"
- );
- /**
- * Attaches the given object to this key.
- */
- public final Object attach(Object ob) {
- return attachmentUpdater.getAndSet(this, ob);
- }
- /**
- * Retrieves the current attachment.
- */
- public final Object attachment() {
- return attachment;
- }
- }