java.nio.channels.SelectionKey
java的nio中,SelectionKey用四个标识来表示可进行的某一事件(某个事件已经发生)
代码
源码如下:
// 插入一个事件
public abstract SelectionKey interestOps(int ops);
// 查询事件
public abstract int readyOps();
// 可进行读
public static final int OP_READ = 1 << 0;
// 可进行写
public static final int OP_WRITE = 1 << 2;
// 已经连接完成,可以进行读写
public static final int OP_CONNECT = 1 << 3;
// 可以接受新的连接
public static final int OP_ACCEPT = 1 << 4;
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;
}
代码中用 (readyOps() & OP_READ) != 0来表示可以进行某个事件的操作(这里为读事件)。
位运算
& 是java的二进制位运算,只有二进制每一位的值都是1时,结果才是1。
即(二进制):
- 1 & 1 = 1
- 0 & 1 = 0
- 1 & 0 = 0
- 0 & 0 = 0
解读
下面这个表格里面有每个标识的二进制和十进制
| readyOps | 十进制 | 二进制 |
|---|---|---|
| OP_READ | 1 | 00000001 |
| OP_WRITE | 4 | 00000100 |
| OP_CONNECT | 8 | 00001000 |
| OP_ACCEPT | 16 | 00010000 |
OP_READ & OP_WRITE 的二进制的&结果
计算过程:
-
OP_READ & OP_WRITE
- 00000001 # OP_READ
- 00000100 # OP_WRITE
- 00000000 # 结果
将四种值进行组合,他们&的结果都是零(二进制00000000),因为它们二进制形式的1都是在不同的位置上。
所以只有readOps()是本身,结果才不为零,因此(readOps() & OP_READ) != 0 表示可以进行读事件。
更进一步
如果readOps()的二进制是00000101的时候,代表的是什么事件?
- 00000101 & OP_READ = 00000101 & 00000001 = 00000001
- 00000101 & OP_WRITE = 00000101 & 00000100 = 00000100
上面运算结果都不为零,代表了读事件&写事件。
那么00000101是怎么来的,可以通过 OP_WRITE | OP_READ = 00000100 | 00000001 = 00000101
可以通过interesOps(int ops)这个方法同时插入读事件&写事件
即:interesOps(OP_WRITE | OP_READ)