问题:服务器端启动后,cpu占用率很高,经常是99%,100%。
原因分析:RecvThread的终止判断条件最初是if (num == -1)//这里的num是指通道读取到buffer中的字节数,当没有数据时,客户端的IntputStream始终没有终止或关闭,
也就是说SocketChannel始终无法读到流的末尾。但是服务器的channel始终在尝试读取客户端的数据,但读取的数据都为空,
这样就使得cpu一直在做“无用功”——空转。
--------------------------------------------------
或许你会问,只不过才一个线程在接收数据而已,不至于使得cpu慢的如老牛耕地吧?你这样说是没错的。但是接下来,我在无意中做了个
小小的实验:我在RecvThread类中加入了运行时的debug信息。
另外,请观众注意,当我们在ListenThread中启动RecvThread并运行的同时,原先的线程ListenThread也没闲着,而是在继续往下执行。
服务器端启动后,我使用客户端发送了一个字符(仅仅是一个字符)给服务器端,意外出现了:服务器的console中打印了不止一个RecvThread线程的debug信息。
为什么会有这么多线程?按照我们的思路,当判断SelectionKey是readable厚,我们只new了一个线程来接收数据啊。而且NIO api中对
Selector的select()方法解释如下:
是啊,没错啊,只有select至少一个有效的通道时,select()才会返回,否则就一直阻塞。
但是,从我刚才的实验中,大家也许很清楚的看到了,其实当RecvThread处理数据的同时,select()方法并没有阻塞,继而它后面的程序仍然会继续执行。
以至于new 了第二个、第三个....第n个RecvThread的实例。
后来我专门又输出了select()的返回值,结果也进一步验证了我刚才所言——RecvThread线程处理数据的同时,select()并没有老老实实的阻塞在那里,而是返回了一个0。
最后,唯一令我感到欣慰的是,这n个线程并不是每一个都接收了客户端发来的数据,而是仅仅其中一个线程接收到了数据。
解决方法:把RecvThread的终止判断条件改成if (num <= 0),并且强烈建议您:不要在selectionKey.isReadable()判断之后,去新建一个线程来接收到来的数据。原因1是因为刚才我所讲的一个消息对应n个线程,将耗费掉大量的cpu资源,
而且这n个线程中为我们做事的却只有其中一个(这也许刚好就是当今经济危机下大部分企业都在裁员的原因)。原因之二,千万不要单纯以为这不过是n个线程而已,
服务器接收客户端消息是很频繁的,一个消息对应n个线程,那么100条消息就对应了.....我想你不会希望看到自己的cpu被这n*100个线程累垮。^_^
分享到:
相关推荐
NULL 博文链接:https://zheng12tian.iteye.com/blog/1094811
javaNIO学习笔记(csdn)————程序
Nio学习笔记
java NIO的基本知识点学习笔记,不包含具体代码
java学习笔记1(java io/nio)设计模式
文章同步:http://blog.csdn.net/wgyscsf/article/details/50953318
使用Java NIO编写高性能的服务器
使用Java_NIO编写高性能的服务器.doc
IO 是主存和外部设备 ( 硬盘、终端和网络等 ) 拷贝数据的过程。 IO 是操作系统的底层功能实现,底层通过 I/O 指令进行...所有语言运行时系统提供执行 I/O 较高级别的工具。 (c 的 printf scanf,java 的面向对象封装 )
jaca视频教程 jaca游戏服务器端开发 Netty NIO AIO Mina视频教程 课程目录: 一、Netty快速入门教程 01、第一课NIO 02、第二课netty服务端 03、第三课netty客户端 04、第四课netty线程模型源码分析(一) 05、...
JAVA NIO学习资料JAVA NIO学习资料
NIO笔记.doc
NULL 博文链接:https://flym.iteye.com/blog/392350
对应文章https://blog.csdn.net/qq_39188039/article/details/86216204
java_nio学习文档
Contents: 1 核心概念以及基本读写 2 缓冲区的实现机制 3 连网与异步IO 4 分散和聚集IO 5 文件锁定
基于事件的 NIO 多线程服务器
用java编写的nio通信的例子,nio是io编程的新版本,比io较流行。同时本例子是适用socket通信的。可以在此基础上,添加您的个人应用。本例子适用于:java通信的学习者,android平台通信的学习者。
使用Java NIO编写高性能的服务器.doc