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. Invoke()的使用

    (最近在看协程) Invoke()方法是一种委托机制 Invoke ( "SendMsg", 3 ), 意思是3秒之后调用 SendMsg() 方法 使用时应该注意以下几点: 1. ...

  2. sqlServer sa用户登陆失败的解决办法

    sqlserver sa用户登陆失败的解决办法 如下图以此模仿: 1.右键-属性 2.找到安全: 3.勾选如图: 4.sa用户密码重置: 5.服务重启:

  3. DFT到FFT的理解

    DFT简化计算理解(FFT)   DFT: WN=e^(-j*2*pi/N) DFT复杂度o(N^2) 降低与N^2的依赖 使N = LM  (L^2+m^2 <= N^2) N点DFT分解为M ...

  4. 手动给kvm虚机挂载lvm卷

    1.查看计算节点上虚机挂载的卷 [root@xgto01n010243186070 ~]# virsh domblklist instance- Target Source ------------- ...

  5. [SinGuLaRiTy] 树链问题

    [SinGuLaRiTy-1035] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 关于树链 树链是什么?这个乍一看似乎很陌生的词汇表达的其 ...

  6. 【大数据系统架构师】0.1 Java编程基础

    1. 初识Java 2. Java语法 快速入门点我 2.1 数据类型和运算符 2.2 流程控制语句 2.3 数组 2.4 类和对象 2.5 OOP三大特性 2.6 集合框架与泛型 2.7 反射机制 ...

  7. winform datagridview某一列设为自动宽度

    如果用displayedcells只会使看见的数据自动列宽,滚动条往下发现后面的没有自动列宽,所以要用allcells就不会出现这个问题

  8. weblogic启动一闪而过

    点击startWebLogic.cmd的时候,一闪而过 我的原因:JAVA_HOME中的路径是不能带有空格:我的电脑是64位的,jdk(32位)安装路径默认带有空格还有括号,所以重新装jdk,装在没有 ...

  9. C#实现WebSocket协议客户端和服务器websocket sharp组件实例解析

    看到这篇文章的题目,估计很多人都会问,这个组件是不是有些显的无聊了,说到web通信,很多人都会想到ASP.NET SignalR,或者Nodejs等等,实现web的网络实时通讯.有关于web实时通信的 ...

  10. PAT天梯赛L3-015 球队食物链

    读题可以知道是DFS,注意一点,题目说的是赢过,所以str[i][j]=‘W',那么g[i][j]=1,str[i][j]='L',g[j][i]=1 然后就常规搜索即可,还有一点就是剪枝,如果没有可 ...