java NIO之SelectedKey
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的更多相关文章
- Java NIO 基础
Java在JDK1.4中引入了 java.nio 类库,为Java进军后端Server和中间件开发打开了方便之门. 一般而言,这里的 nio 代表的是 New I/O,但是从实质上来说,我们可以将其理 ...
- Java NIO读书笔记2
一.选择器(Selector) Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel ...
- 高吞吐高并发Java NIO服务的架构(NIO架构及应用之一)
高吞吐高并发Java NIO服务的架构(NIO架构及应用之一) http://maoyidao.iteye.com/blog/1149015 Java NIO成功的应用在了各种分布式.即时通信和中 ...
- Java NIO API详解
在JDK 1.4以前,Java的IO操作集中在java.io这个包中,是基于流的同步(blocking)API.对于大多数应用来说,这样的API使用很方便,然而,一些对性能要求较高的应用,尤其是服务端 ...
- Java NIO API详解(转)
原文连接: http://www.blogjava.net/19851985lili/articles/93524.html 感谢原作者 NIO API 主要集中在 java.nio 和它的 subp ...
- (四:NIO系列) Java NIO Selector
出处:Java NIO Selector 1.1. Selector入门 1.1.1. Selector的和Channel的关系 Java NIO的核心组件包括: (1)Channel(通道) (2) ...
- <转>Java NIO API
Java NIO API详解 NIO API 主要集中在 java.nio 和它的 subpackages 中: java.nio 定义了 Buffer 及其数据类型相关的子类.其中被 java.ni ...
- 源码分析netty服务器创建过程vs java nio服务器创建
1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...
- 支撑Java NIO 与 NodeJS的底层技术
支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...
随机推荐
- WinForm中ListBox的使用
获取选中数据:listbox.SelectedItem as XXX 重绘每一行item DrawMode设置为DrawMode.OwnerDrawVariable 然后实现DrawItem(obje ...
- Docker 镜像的制作和使用
镜像 Layer(层) 镜像里的内容是按「层」来组织的,「层」可以复用,一个完整的镜像也可以看做是一个「层」.多个「层」叠加在一起就形成了一个新的镜像,这个镜像也可以作为别的镜像的基础「层」进行更加复 ...
- Kotlin 函数和函数表达式
学习了kotlin 的控制. 其中最为强大的是各种控制可以直接作为表达式来使用. 那么在kotlin中,函数也是可以作为表达式来使用. 而且kotlin中函数的创建方式有很多方式. 第一种: 传统创建 ...
- Atcoder Grand Contest 032C(欧拉回路,DFS判环)
#include<bits/stdc++.h>using namespace std;int vis[100007];vector<int>v[100007];vector&l ...
- 浏览器HTTP_USER_AGENT汇总——Firefox、Chrome、IE9、IE8、IE7、IE6
结论: 浏览器 \ OS XP(IE6) XP(IE7) XP(IE8) Win7 x64(IE9) 猎豹浏览器2.0急速模式 Chrome/21 猎豹浏览器2.0兼容模式 IE6 ...
- Tensorflow博文列表
tensorflow:https://wenku.baidu.com/view/489ecc9727fff705cc1755270722192e44365853.html 语义分割SegNet:htt ...
- 使用Jenkins进行Android自动打包,自定义版本号等信息【转】
之前App在提交测试和最终部署的过程中App打包一直是由开发人员来完成的,由于项目比较大, 再加上Android打包本身就比较慢,所以每次打包还是很耗时的.并且按照严格的研发流程来讲,开发人员应该只负 ...
- asp web服务
项目名--->添加--->web引用 网址:http://www.webxml.com.cn/zh_cn/index.aspx https://blog.csdn.net/linshich ...
- get请求和post的请求的区别
https://www.cnblogs.com/logsharing/p/8448446.html
- php 实现无限极分类
原始数据 $array = array( array('id' => 1, 'pid' => 0, 'n' => '河北省'), array('id' => 2, 'pid' ...