- 浏览: 545138 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (618)
- java (109)
- Java web (43)
- javascript (52)
- js (15)
- 闭包 (2)
- maven (8)
- 杂 (28)
- python (47)
- linux (51)
- git (18)
- (1)
- mysql (31)
- 管理 (1)
- redis (6)
- 操作系统 (12)
- 网络 (13)
- mongo (1)
- nginx (17)
- web (8)
- ffmpeg (1)
- python安装包 (0)
- php (49)
- imagemagic (1)
- eclipse (21)
- django (4)
- 学习 (1)
- 书籍 (1)
- uml (3)
- emacs (19)
- svn (2)
- netty (9)
- joomla (1)
- css (1)
- 推送 (2)
- android (6)
- memcached (2)
- docker、 (0)
- docker (7)
- go (1)
- resin (1)
- groovy (1)
- spring (1)
最新评论
-
chokee:
...
Spring3 MVC 深入研究 -
googleyufei:
很有用, 我现在打算学学Python. 这些资料的很及时.
python的几个实用网站(转的) -
hujingwei1001:
太好了找的就是它
easy explore -
xiangtui:
例子举得不错。。。学习了
java callback -
幻影桃花源:
太好了,謝謝
Spring3 MVC 深入研究
原文地址:http://blog.csdn.net/hepeng19861212/article/details/4479714
问题:服务器端启动后,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()方法解释如下:
[java] view plaincopy
public abstract int select()
throws IOException
选择一组键,其相应的通道已为 I/O 操作准备就绪。
此方法执行处于阻塞模式的选择操作。仅在至少选择一个通道、调用此选择器的 wakeup 方法,或者当前的线程已中断(以先到者为准)后此方法才返回。
是啊,没错啊,只有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个线程累垮。^_^
问题:服务器端启动后,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()方法解释如下:
[java] view plaincopy
public abstract int select()
throws IOException
选择一组键,其相应的通道已为 I/O 操作准备就绪。
此方法执行处于阻塞模式的选择操作。仅在至少选择一个通道、调用此选择器的 wakeup 方法,或者当前的线程已中断(以先到者为准)后此方法才返回。
是啊,没错啊,只有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个线程累垮。^_^
发表评论
-
Django静态文件处理总结
2015-05-13 13:59 502原文地址:http://blog.csdn.net/wenxu ... -
原 异步非阻塞机制与多线程阻塞机制在处理并发耗时等待任务上的效率对比分析
2015-04-21 10:05 659原文地址:http://my.oschina.net/mall ... -
Django报错“_mysql_exceptions.Warning: Incorrect string value: ‘\xE6\xB5…’ for colu
2015-03-25 15:50 962原文地址:http://www.tuicool.com/art ... -
django使用mysql时的中文存储问题 - [python]
2015-03-25 15:36 1467原文地址:http://www.blogbus.com/831 ... -
python 调用 php 实例
2014-06-23 14:09 2596原文地址:http://hi.baidu.com/ji_hai ... -
php调用python
2014-06-23 14:08 761原文地址:http://blog.163.com/darwin ... -
uwsgi python ssl编译问题记录
2014-06-19 14:24 847uwsgi python ssl编译问题记录 发表于6个月前( ... -
python2.7 安装ssl模块
2014-06-19 14:22 3169python2.7 安装ssl模块 2012-02-28 13 ... -
Centos6.5下升级Python 2.6.6 to python 2.7.3
2014-06-19 13:53 634Centos6.5下升级Python 2.6.6 to pyt ... -
翻译:redis-py 说明文件 (2012-05-30 17:55:52)
2014-06-04 10:22 430翻译:redis-py 说明文件 (2012-05-30 17 ... -
关于Redis的Python客户端的连接池问题
2014-06-04 10:21 597关于Redis的Python客户端的连接池问题 在一 ... -
Windows下 Python 安装包的配置
2014-03-22 10:23 6191、下载安装 Python python-2.7.2.msi ... -
[翻译]深入理解Tornado——一个异步web服务器
2014-03-07 15:16 1604[翻译]深入理解Tornado— ... -
多版本Python共存[支持使用pip安装包]
2014-02-28 10:59 1109多版本Python共存[支持使 ... -
Django 数据库访问性能优化
2013-09-05 15:22 659Django 数据库访问性 ... -
Python六大开源框架对比:Web2py略胜一筹
2013-08-21 11:29 794Python是一门动态、面向对象语言。其最初就是作为一门面向 ... -
Python 代码调试技巧
2013-08-15 18:11 845使用 pdb 进行调试 pdb 是 python 自带的 ... -
python urlencode 编码
2013-07-05 13:28 935urlencode 调用方法 urlencode的参 ... -
window下使用virtualenv
2013-06-30 15:26 1080--- window下使用virtualenv -- ... -
浅析python的metaclass
2013-06-30 11:12 764分享下自己对python的met ...
相关推荐
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 的面向对象封装 )
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 文件锁定
jaca视频教程 jaca游戏服务器端开发 Netty NIO AIO Mina视频教程 课程目录: 一、Netty快速入门教程 01、第一课NIO 02、第二课netty服务端 03、第三课netty客户端 04、第四课netty线程模型源码分析(一) 05、...
基于事件的 NIO 多线程服务器
用java编写的nio通信的例子,nio是io编程的新版本,比io较流行。同时本例子是适用socket通信的。可以在此基础上,添加您的个人应用。本例子适用于:java通信的学习者,android平台通信的学习者。
使用Java NIO编写高性能的服务器.doc