SelectedKey是channel与Selector绑定的标记,每将一个channel注册到一个selector就会产生一个SelectedKey,并将这个SelectedKey放入到Selected的key set中,注意,key set 只能通过这种方式添加,不可以直接添加,但是可以手动移除。

SelectedKey存在着两个集合,分别是interest set和ready set,二者的元素类型都是整数值,每一位代表一个标记,代表该key对应的channel支持/准备好什么操作。interest set在SelectedKey被创建时(channel注册时)指定,记录了此key对应的channel支持什么操作(accept,write,read,connect等),并且可以在以后通过interestOpt(int)改变;ready set则记录了此SelectedKey已经准备好了什么样的操作,ready set的值由selector设置和更新,不可以由用户去改变。ready set指定的操作说明该种操作已经就绪好,可以实行非阻塞操作了,但是不保证之后该key状态没有被修改(比如channel被关闭),如果之后key状态被改变又没有通过select操作更新(参见java.nio.channels.Selector),则操作可能依然会阻塞线程。

SelectedKey为每种操作标记都定义了一个静态常量值,但是一个key具体指示什么操作,是由对应的channel决定的,SelectedChannel的各个子类都有自己所支持的操作,如果注册时被制定了不支持的操作,将会发生运行时错误。

SelectedKey还为应用程序提供了一个附件区,可用于存放上层应用协议相关的数据,比如协议状态等。这个附件区是一个单独的对象,用attach设置,attachment获取。

SelectedKey本身不是线程安全的,但是,操作它的selector要求实现同步措施,对数据的读写加上不同程度的同步锁。也就是说,同步策略交给具体的selector实现去做。

典型的NIO socket服务端代码如下所示:

public class PlainNioServer {
public void serve(int port) throws IOException {
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
ServerSocket ss = serverChannel.socket();
InetSocketAddress address = new InetSocketAddress(port);
ss.bind(address); //
Selector selector = Selector.open(); //2
serverChannel.register(selector, SelectionKey.OP_ACCEPT); //3
final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());
for (; ; ) {
try {
selector.select(); //4
} catch (IOException ex) {
ex.printStackTrace();
// handle exception
break;
}
Set<SelectionKey> readyKeys = selector.selectedKeys(); //5
Iterator<SelectionKey> iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
try {
if (key.isAcceptable()) { //6
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel client = server.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, msg.duplicate()); //
System.out.println("Accepted connection from " + client);
}
if (key.isWritable()) { //8
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer buffer = (ByteBuffer) key.attachment();
while (buffer.hasRemaining()) {
if (client.write(buffer) == 0) { //9
break;
}
}
client.close(); //10
}
} catch (IOException ex) {
key.cancel();
try {
key.channel().close();
} catch (IOException cex) { // 在关闭时忽略
}
}
}
}
}
}

java NIO之SelectedKey的更多相关文章

  1. Java NIO 基础

    Java在JDK1.4中引入了 java.nio 类库,为Java进军后端Server和中间件开发打开了方便之门. 一般而言,这里的 nio 代表的是 New I/O,但是从实质上来说,我们可以将其理 ...

  2. Java NIO读书笔记2

    一.选择器(Selector) Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel ...

  3. 高吞吐高并发Java NIO服务的架构(NIO架构及应用之一)

    高吞吐高并发Java NIO服务的架构(NIO架构及应用之一) http://maoyidao.iteye.com/blog/1149015   Java NIO成功的应用在了各种分布式.即时通信和中 ...

  4. Java NIO API详解

    在JDK 1.4以前,Java的IO操作集中在java.io这个包中,是基于流的同步(blocking)API.对于大多数应用来说,这样的API使用很方便,然而,一些对性能要求较高的应用,尤其是服务端 ...

  5. Java NIO API详解(转)

    原文连接: http://www.blogjava.net/19851985lili/articles/93524.html 感谢原作者 NIO API 主要集中在 java.nio 和它的 subp ...

  6. (四:NIO系列) Java NIO Selector

    出处:Java NIO Selector 1.1. Selector入门 1.1.1. Selector的和Channel的关系 Java NIO的核心组件包括: (1)Channel(通道) (2) ...

  7. <转>Java NIO API

    Java NIO API详解 NIO API 主要集中在 java.nio 和它的 subpackages 中: java.nio 定义了 Buffer 及其数据类型相关的子类.其中被 java.ni ...

  8. 源码分析netty服务器创建过程vs java nio服务器创建

    1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...

  9. 支撑Java NIO 与 NodeJS的底层技术

    支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...

随机推荐

  1. 独立部署GeoWebCache

    在进行GIS项目开发中,常使用Geoserver作为开源的地图服务器,Geoserver是一个JavaEE项目,常通过Tomcat进行部署.而GeoWebCache是一个采用Java实现用于缓存WMS ...

  2. Android Camera相机功能实现 拍照并保存图片

    AndroidManifest.xml <uses-feature android:name="android.hardware.camera"/> <uses- ...

  3. 十、Node.js-url模块

    下面使用之前提到过的note交互模式(可以在cmd直接执行js代码)进行学习url模块 跳出note模式同样是Ctrl+C(两次) 学习url模块主要是要掌握url模块的方法: url.parse() ...

  4. 一、认识Node.js

    1.什么是Note.js? 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个 Javascript 运行环境(runtime).它让 JavaScript 可 ...

  5. 【大数据系统架构师】0.2 Linux基础

    1. Linux基本环境 1.1 大数据Hadoop前置大纲讲解 1)Linux系统,基本命令 2)Java语言,JavaSE相关知识 3)MySQL基本的DML和DDL 1.2 常见Linux系统. ...

  6. 金庸笔下的"程序员" | 附金庸武侠全集

    金庸 飞雪连天射白鹿,笑书神侠倚碧鸳当您八十高龄取得牛津大学唐朝史学博士学位,我还以为这是另一部史诗开始的信号,然而没有后续了.我的高中到大学,是十遍<笑傲江湖>的距离,我的整个青春,是大 ...

  7. 【ARC080F】Prime Flip 差分+二分图匹配

    Description ​ 有无穷个硬币,初始有n个正面向上,其余均正面向下.  你每次可以选择一个奇质数p,并将连续p个硬币都翻转.  问最小操作次数使得所有硬币均正面向下. Input ​ 第一行 ...

  8. JavaScript学习笔记——2.数据类型与类型转换

    数据类型 JS中一共分成六种数据类型 1- String 字符串 2- Number 数值 3- Boolean 布尔值 4- Null 空值 5- Undefined 未定义 6- Object 对 ...

  9. Azure KUDU工具

    Azure网站提供了一个比较不错可以用来对我们的网站进行分析的工具------KUDU,下面我们就来看看这个工具主要能为我们做些啥,啥时候使用它. 如何打开KUDU KUDU所展现的强大功能 如何打开 ...

  10. Python实现KNN算法

    Python实现Knn算法 关键词:KNN.K-近邻(KNN)算法.欧氏距离.曼哈顿距离  KNN是通过测量不同特征值之间的距离进行分类.它的的思路是:如果一个样本在特征空间中的k个最相似(即特征空间 ...