SelectionKey理解(总结)
SelectKey注册了写事件,不在合适的时间去除掉,会一直触发写事件,因为写事件是代码触发的
client.register(selector, SelectionKey.OP_WRITE);
或者sk.interestOps(SelectionKey.OP_WRITE)
执行了这以上任一代码都会无限触发写事件,跟读事件不同,一定注意
nio的select()的时候,只要数据通道允许写,每次select()返回的OP_WRITE都是true。所以在nio的写数据里面,我们在每次需要写数据之前把数据放到缓冲区,并且注册OP_WRITE,对selector进行wakeup(),这样这一轮select()发现有OP_WRITE之后,将缓冲区数据写入channel,清空缓冲区,并且反注册OP_WRITE,写数据完成。
这里面需要注意的是,每个SocketChannel只对应一个SelectionKey,也就是说,在上述的注册和反注册OP_WRITE的时候,不是通过channel.register()和key.cancel()做到的,而是通过key.interestOps()做到的。代码如下:
public void write(MessageSession session, ByteBuffer buffer) throws ClosedChannelException {
SelectionKey key = session.key();
if((key.interestOps() & SelectionKey.OP_WRITE) == 0) {
key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
}
try {
writebuf.put(buffer);
} catch(Exception e) {
System.out.println("want put:"+buffer.remaining()+", left:"+writebuf.remaining());
e.printStackTrace();
}
selector.wakeup();
}
.....
while(true) {
selector.select();
.....
if(key.isWritable()) {
MessageSession session = (MessageSession)key.attachment();
//System.out.println("Select a write");
synchronized(session) {
writebuf.flip();
SocketChannel channel = (SocketChannel)key.channel();
int count = channel.write(writebuf);
//System.out.println("write "+count+" bytes");
writebuf.clear();
key.interestOps(SelectionKey.OP_READ);
}
}
......
}
要点一:不推荐直接写channel,而是通过缓存和attachment传入要写的数据,改变interestOps()来写数据;
要点二:每个channel只对应一个SelectionKey,所以,只能改变interestOps(),不能register()和cancel()。
SelectionKey理解(总结)的更多相关文章
- Java NIO Selector 的使用
之前的文章已经把 Java 中 NIO 的 Buffer.Channel 讲解完了,不太了解的可以先回过头去看看.这篇文章我们就来聊聊 Selector -- 选择器. 首先 Selector 是用来 ...
- Java提高班(五)深入理解BIO、NIO、AIO
导读:本文你将获取到:同/异步 + 阻/非阻塞的性能区别:BIO.NIO.AIO 的区别:理解和实现 NIO 操作 Socket 时的多路复用:同时掌握 IO 最底层最核心的操作技巧. BIO.NIO ...
- 一文让你彻底理解 Java NIO 核心组件
背景知识 同步.异步.阻塞.非阻塞 首先,这几个概念非常容易搞混淆,但NIO中又有涉及,所以总结一下. 同步:API调用返回时调用者就知道操作的结果如何了(实际读取/写入了多少字节). 异步:相对于同 ...
- 深入理解JAVA中的NIO
前言: 传统的 IO 流还是有很多缺陷的,尤其它的阻塞性加上磁盘读写本来就慢,会导致 CPU 使用效率大大降低. 所以,jdk 1.4 发布了 NIO 包,NIO 的文件读写设计颠覆了传统 IO 的设 ...
- 一文理解 Java NIO 核心组件
同步.异步.阻塞.非阻塞 首先,这几个概念非常容易搞混淆,但NIO中又有涉及,所以总结一下[1]. 同步:API调用返回时调用者就知道操作的结果如何了(实际读取/写入了多少字节). 异步:相对于同步, ...
- 深入理解 java I/O
Java 的 I/O 类库的基本架构 I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道.在当今这个数据大爆炸时代, ...
- BIO,NIO,AIO(NIO2)的理解
写在前面,这里所说的IO主要是强调的网络IO 1.BIO(同步并阻塞) 客户端一个请求对应一个线程.客户端上来一个请求(最开始的连接以及后续的IO请求),服务端新建一个线程去处理这个请求,由于线程总数 ...
- IO、NIO、AIO理解
摘要: 关于BIO和NIO的理解 最近大概看了ZooKeeper和Mina的源码发现都是用Java NIO实现的,所以有必要搞清楚什么是NIO.下面是我结合网络资料自己总结的,为了节约时间图示随便画的 ...
- Java NIO理解与使用
https://blog.csdn.net/qq_18860653/article/details/53406723 Netty的使用或许我们看着官网user guide还是很容易入门的.因为java ...
随机推荐
- oc_转_NSInteger 和 NSNumber
Objective-C 支持的类型有两种:基本类型和类. 基本类型,如同 C 语言中的 int 类型一样,拿来就可以直接用.而类在使用时,必须先创建一个对象,再为对象分配空间,接着做初始化和赋值.类的 ...
- CentOS安装XRDP实现远程桌面访问
1.配置环境: yum install gcc pam-devel openssl-devel -y 2.进入指定目录下载并解压xrdp: 先安装 wget; sudo yum -y install ...
- 如何学习java ee
来看看Sun给出的J2EE 相关技术主要分为几大块. 1. Web Service技术 - Java API for XML Processing (JAXP) - Java API for XM ...
- [IoC容器Unity] :Unity预览
1.引言 高内聚,低耦合成为一个OO架构设计的一个参考标准.高内聚是一个模块或者一个类中成员跟这个模块或者类的关系尽量高,低耦合是不同模块或者不同类之间关系尽量简单. 拿咱国家举例来说,假如你是中国人 ...
- angurlajs 如何绑定Jquery
//绑定Jqueryfunction bindJQuery() { // bind to jQuery if present; jQuery = window.jQuery;//获取windows 的 ...
- Banach—steinhaus定理的应用
- 【转】安装Intel HAXM为Android 模拟器加速,30秒内启动完成
http://www.cnblogs.com/Li-Cheng/p/4351966.html http://www.cnblogs.com/csulennon/p/4178404.html https ...
- Ping批量函数
function pingm ($file){ $ips = gc $file foreach ($ip in $ips) { $cmdline +="ping " + $ip + ...
- 【转】python的内存管理机制
http://developer.51cto.com/art/201007/213585.htm 内存管理,对于Python这样的动态语言,是至关重要的一部分,它在很大程度上甚至决定了Python的执 ...
- 2015南阳CCPC C - The Battle of Chibi DP
C - The Battle of Chibi Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description Cao Cao made up a ...