文章标题
来源:互联网 发布:淘宝网天猫女西装外套 编辑:程序博客网 时间:2024/05/22 15:00
《Java 源码分析》:Java NIO 之 SelectionKey
在ServerSocketChannel源码分析中我们知道当把一个channel注册到指定的Selector上时,
实际上就是将(channel,selector)封装成了一个SelectionKey对象,并将此对象保存在了Selector对象中。
SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);
在Java NIO 的一些小Demo中,我们常常会看见这样的代码:
// 当注册事件到达时,方法返回,否则该方法会一直阻塞 selector.select(); // 获得selector中选中的相的迭代器,选中的相为注册的事件 Set<SelectionKey> set = selector.selectedKeys(); Iterator<SelectionKey> ite = set.iterator(); while(ite.hasNext()){ SelectionKey selectionKey = (SelectionKey) ite.next(); // 删除已选的key 以防重负处理 ite.remove(); if(selectionKey.isAcceptable()){//如果有客户端连接进来 //先拿到这个SelectionKey里面的ServerSocketChannel。 ServerSocketChannel serverSocketChannel = (ServerSocketChannel)selectionKey.channel(); // do something.... } }
今天我们就来看下这个类.
SelectionKeyImpl类中的几个重要属性如下:
final SelChImpl channel; 所拥有的channel对象,该属性是包私有的final SelectorImpl selector; 所拥有的selector对象,该属性是包私有的 // Index for a pollfd array in Selector that this key is registered withprivate int index; //其值表示该SelectionKey对象存储在与其关联的Selector对象中所在的位置private volatile int interestOps; //集合private int readyOps;
构造方法
SelectionKeyImpl(SelChImpl ch, SelectorImpl sel) { channel = ch; selector = sel;}
以下是这个类中用来获取该对象中所关联的 channel、selector的方法
public SelectableChannel channel() { return (SelectableChannel)channel;}public Selector selector() { return selector;}int getIndex() { // package-private return index;}void setIndex(int i) { // package-private index = i;}
都比较简单,容易理解哈。
在编程中我们使用channel.register(selector,interestSet)方法来将channel注册到指定的selector中。这个方法的第二个参数。这是一个“interest集合”,意思是在通过Selector监听此Channel时对什么事件感兴趣。可以监听四种不同类型的事件:
1、Connect
2、Accept
3、Read
4、Write
通道channel触发了一个事件的意思是该事件已经就绪。所以,如果某个channel成功连接到另一个服务器称为“连接就绪”。如果一个ServerSocketChannel准备好接收新进入的连接称为“接收就绪”。如果一个有数据可读的通道可以说是“读就绪”。等待写数据的通道可以说是“写就绪”。
这四种事件用SelectionKey的四个常量来表示,如下:
1、SelectionKey.OP_CONNECT
2、SelectionKey.OP_ACCEPT
3、SelectionKey.OP_READ
4、SelectionKey.OP_WRITE
如果你对不止一种事件感兴趣,那么可以用“位或”操作符将常量连接起来,如下:
int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
在SelectionKey类的源码中我们可以看到如下的4中属性,四个变量用来表示四种不同类型的事件:可读、可写、可连接、可接受连接
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;
SelectionKey类还提供了以下几个方法用来检测channel中什么事件或操作已经就绪
//测试此通道是否可读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;}//测试这个SelectionKey对应的通道是否已经接受了一个新的Socket连接。public final boolean isAcceptable() { return (readyOps() & OP_ACCEPT) != 0;}
小结
以上,我们就简单的看了下SelectionKey类,SelectionKey类简单来说就是一个辅助类,比较简单。
- 文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题 文章标题 文章标题 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- linux下设置免密登陆
- setCompoundDrawables使用
- js中Date日期格式转换以及时间和毫秒之间的转换
- 从人脑研究入手_使人工智能不再“四肢发达_头脑简单”
- 【leetcode】surrended-regions
- 文章标题
- 1小时轻松学会用Excel做数据分析
- AndroidStudio打包时的错误UnsupportedOperationException
- JavaScript正则表达式在线测试工具
- URL:统一资源定位符
- 最长公共子序列&回文字符串 nyoj动态规划
- php常见问题列表
- LTE DRX in IDLE
- 数据科学家们正在使用的十种程序语言和工具