NIO 多线程
本文可看成是对Doug Lea Scalable IO in Java一文的翻译。
当前分布式计算 Web Services盛行天下,这些网络服务的底层都离不开对socket的操作。他们都有一个共同的结构:
1. Read request
2. Decode request
3. Process service
4. Encode reply
5. Send reply
经典的网络服务的设计如下图,在每个线程中完成对数据的处理:
但这种模式在用户负载增加时,性能将下降非常的快。我们需要重新寻找一个新的方案,保持数据处理的流畅,很显然,事件触发机制是最好的解决办法,当有事件发生时,会触动handler,然后开始数据的处理。
Reactor模式类似于AWT中的Event处理:
Reactor模式参与者
1.Reactor 负责响应IO事件,一旦发生,广播发送给相应的Handler去处理,这类似于AWT的thread
2.Handler 是负责非堵塞行为,类似于AWT ActionListeners;同时负责将handlers与event事件绑定,类似于AWT addActionListener
如图:
Java的NIO为reactor模式提供了实现的基础机制,它的Selector当发现某个channel有数据时,会通过SlectorKey来告知我们,在此我们实现事件和handler的绑定。
我们来看看Reactor模式代码:
public class Reactor implements Runnable{
final Selector selector; Reactor(int port) throws IOException { serverSocket.configureBlocking(false); logger.debug("-->Start serverSocket.register!"); //利用sk的attache功能绑定Acceptor 如果有事情,触发Acceptor public void run() { // normally in a new Thread //运行Acceptor或SocketReadHandler } class Acceptor implements Runnable { // inner |
以上代码中巧妙使用了SocketChannel的attach功能,将Hanlder和可能会发生事件的channel链接在一起,当发生事件时,可以立即触发相应链接的Handler。
再看看Handler代码:
public class SocketReadHandler implements Runnable {
public static Logger logger = Logger.getLogger(SocketReadHandler.class); private Test test=new Test(); final SocketChannel socket; static final int READING = 0, SENDING = 1; public SocketReadHandler(Selector sel, SocketChannel c) socket = c; socket.configureBlocking(false); //将SelectionKey绑定为本Handler 下一步有事件触发时,将调用本类的run方法。 //同时将SelectionKey标记为可读,以便读取。 public void run() { /** ByteBuffer input = ByteBuffer.allocate(1024); int bytesRead = socket.read(input); ...... //激活线程池 处理这些request ..... }catch(Exception e) { } |
注意在Handler里面又执行了一次attach,这样,覆盖前面的Acceptor,下次该Handler又有READ事件发生时,将直接触发Handler.从而开始了数据的读 处理 写 发出等流程处理。
将数据读出后,可以将这些数据处理线程做成一个线程池,这样,数据读出后,立即扔到线程池中,这样加速处理速度:
更进一步,我们可以使用多个Selector分别处理连接和读事件。
一个高性能的Java网络服务机制就要形成,激动人心的集群并行计算即将实现。
NIO 多线程的更多相关文章
- 基于事件的 NIO 多线程服务器--转载
JDK1.4 的 NIO 有效解决了原有流式 IO 存在的线程开销的问题,在 NIO 中使用多线程,主要目的已不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个 CPU 的处 ...
- 网络编程 -- RPC实现原理 -- NIO多线程 -- 迭代版本V2
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V2——增加WriteQueue队列,存放selectionKey.addWriteEventToQueue()添加selectionKey并唤醒阻 ...
- Java Nio 多线程网络下载
--> 默认最多50个线程 同一文件下载失败延迟超过30秒就结束下载 --> 下载5分钟超时时间,假设5分钟内未下载完就结束下载 --> 依赖 commons-httpclient ...
- 网络编程 -- RPC实现原理 -- NIO多线程 -- 迭代版本V1
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V1——设置标识变量selectionKey.attach(true);只处理一次(会一直循环遍历selectionKeys,占用CPU资源). ( ...
- JAVA NIO 结合多线程
NIO 的选择器采用了多路复用(Multiplexing)技术,可在一个选择器上处理多个套接字, 通过获取读写通道来进行 IO 操作.由于网络带宽等原因,在通道的读.写操作中是容易出现等待的, 所以在 ...
- NIO服务器
导语 NIO的出现是为服务器端编程而设计的.它的作用就是能够让一个线程为多个连接服务.NIO中的API都是非阻塞模式的,这样可以在服务器端采用异步的方式来处理多个请求.NIO中有两个重要的东西就是通道 ...
- Java NIO 操作总结
问题: 1.Java NIO 出现大量CLOSE_WAIT或TIME_WAIT的端口无法释放 CLOSE_WAIT: 参考:http://my.oschina.net/geecoodeer/blog/ ...
- 全面解读Java NIO工作原理(4)
全面解读Java NIO工作原理(4) 2011-12-14 10:31 Rollen Holt Rollen Holt的博客 我要评论(0) 字号:T | T JDK 1.4 中引入的新输入输出 ( ...
- NIO[读]、[写]在同一线程(单线程)中执行,让CPU使用率最大化,提高处理效率
前几天写过一篇文章,讨论重写服务后,用ab进行压力测试,发现使用NIO后没提高什么性能,只是CPU使用率提高了,内存占用降低了. 之前的NIO实现模式,主要参考(基于事件的NIO多线程服务器)http ...
随机推荐
- ubuntu14.04使用root用户登录桌面
ubuntu安装好之后,默认是不能用root用户登录桌面的,只能使用普通用户或者访客登录.怎样开启root用户登录桌面呢? 先用普通用户登录,然后切换到root用户,然后执行如下命令: vi /usr ...
- Ubuntu文件中文乱码
如图,该文件在gedit打开中文显示正常 在命令行中用vim打开,显示内容如下: 使用命令进行编码转换 iconv -f gbk -t utf8 ./SogouQ.mini > ./sougou ...
- 从websphere6.1迁移到weblogic10.3的问题总结
系统采用war包的方式部署. 问题一: ####<2011-3-29 下午05时17分43秒 CST> <Info> <ServletContext-/MIS-be ...
- 【一天一道LeetCode】#87. Scramble String
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- ROS(indigo)_turtlebot仿真示例包括stage和gazebo
ROS(indigo)_turtlebot仿真示例包括stage和gazebo 现上参考网址: turtlebot:http://wiki.ros.org/Robots/TurtleBot stage ...
- UI设计切忌墨守成规,但改变也须用数据说话
因为我提倡一种非标准的方法,Jon Galloway在一段评论里点了我的名: 年,他们很清楚怎么去填写这些表单.如果采用其他方法,用户会感到困惑,有些人还会落荒而逃(丢掉购物车,等等).Web表单很有 ...
- Spring BeanFacoty doCreateBean方法分析
上一篇,我们分析到了doCreateBean,现在继续: 先看看时序图 protected Object doCreateBean(final String beanName, final RootB ...
- nginx 安装php
1. 安装PHP 5.5.0 下载 1 2 cd /usr/local/src/ wget http://www.php.net/get/php-5.5.0.tar.bz2/from/jp1.ph ...
- Java实现附近地点搜索
Java,Mysql-根据一个给定经纬度的点,进行附近500米地点查询–合理利用算法 最近做一个项目:需要查询一个站点(已知该站点经纬度)1km-10km范围内的其它站点.所以,我首先想到的是,对每条 ...
- Ext JS 5 beta版发布
原文:Announcing Public Beta of Ext JS 5 我们非常高兴的宣布,Sencha Ext JS 5 beta版本开始进行公测了.这个beta版本可以让你.我们Sencha社 ...