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;
}
}