Java NIO的多路复用及reactor
(from:http://developer.51cto.com/art/201112/306489.htm)
以下描述,为了说明问题,就提提历史(类似的东西,网上一搜一大把,但是希望你能在这里止步,知道到底是怎么回事。如果还是不清楚,咱就站内沟通!)。
在我(刚)看nio的这段时间里,主要接触了几个东西,就是关于server和client。java之前的io完全可以胜任,但是效率不高,为何效率不高呢?
===============history==start===============
//TODO:finish the old style of server and socket data transion.
ServerSocket socket = new ServerSocket(80);
while (true) {
final Socket connection = socket.accept();
handleRequest(connection);
}
===============history==end in the future================
在上面的代码片段中,我们只能是一个request一个的进行处理。这使得所有的请求都阻塞了。如果我们再改变一下,将handleRequest方法封装到线程中处理:
- if(connection = null){
- new Thread(new Runnable(){
- public void run(){
- handleRequest(connection);
- }
- public void handleRequest(Socket conn){
- //do actions
- }
- }).start();
- }
服务器端的资源是有限的,我们这里仅仅是从线程角度来扩展,但是这种处理依然是阻塞的处理方式。首先,仅仅是建立连接(socket),就占用了服务器的线程资源。如果客户端还没有发出相应的数据请求,那么服务器就要一直等待他们的数据流过来,然后再进行读取,如此往复。。。一直都blocking。服务器处在一个高负荷状态中。
NIO出来之后,进入改革开放时期,有了这么几个角色,ServerSocketChannel,SelectionKey,Selector。
这几个角色都是做什么用的呢?需要了解一下reactor模式(反应堆模式)。
作为服务端,如果什么操作都要依赖于客户端,很多操作都阻塞,如上面的代码片段所示。reactor模式提供了一种很好的事件处理机制,以分离事件处理对象与事件之间的耦合。如下图示(详细请看参考资料(1)):
说明:
Acceptor就是我们Server端的主要任务消化者;
Initiation Dispatcher是事件(Event)的分发者;
HTTP Handler是具体操作人。
首先,在Initiation Dispatcher中注册一个acceptor(1:register Acceptor),这个Acceptor是跟事件绑定的,它仅仅关心某种事件(event)。
Initiation Dispatcher不断地循环获取请求过来的事件(2:handle events),如果发现有对应Acceptor关心的事件(3:connect),通知Acceptor有事件发生(4:new connection)。
Acceptor针对此事件进行处理,创建了新的HTTP Handler((5:create handler))
一轮事件获取和分发完成。
那么handler是不是就抓住这个connection不放,然后一直苦苦等待数据流的到来呢?
不是的,它也是将自己和自己关心的事件注册到Initiation Dispatcher。如果Initiation Dispatcher在handle Events时发现了它关心的事件,那么就会交由它去进行相应处理。如下图示,在连接完成后,browser提交的get请求,handler的处理过程:
这里面尤其要注意到,2:read ready,之后才read request,也就是说,handler在dispatcher中注册了自己关心的事件(READ),然后在写的时候,也是类似情况。
以上的过程就实现了非阻塞的处理方式,客户端的连接可以非阻塞(这是意思是,acceptor不必一直苦苦等候),然后对客户端过来的request内容,也是非阻塞(这里是不必苦苦等待其数据的到来),都是不必一直眼巴巴的看着那个连接,那些数据,而是如果有我关心的事件了,我再进行处理,期间完全相信Initiation Dispatcher就行了。
这里有一点要注意,就是现在的reactor模式都是建立在操作系统的基础上实现的,不同的操作系统有不同的实现方式。而且都不支持多线程(针对Initiation Dispatcher而言)。
有了上面的理解之后,来给NIO中的对象跟reactor的对象对个象。
Acceptor:ServerSocketChannel;
Initiation Dispatcher:Selector;
HTTP Handler:针对SocketChannel进行实际处理的个性化对象;
Events:在SelectionKey中:
static int |
OP_ACCEPT Operation-set bit for socket-accept operations. |
static int |
OP_CONNECT Operation-set bit for socket-connect operations. |
static int |
OP_READ Operation-set bit for read operations. |
static int |
OP_WRITE Operation-set bit for write operations. |
Operation-set bit for write operations. 经过上面的描述,我们就可以写出基于NIO的非阻塞Server啦。具体的代码示例大家可以看参考资料
参考资料:
(1)华盛顿大学计算机科学的一篇关于proactor的论文,非常详细。同时这篇文章中还有 reactor的改进版proactor,各位可以一饱眼福。
(2)简单的NIO server实现代码,但是这个代码中在写的部分有些瑕疵,各位根据上面的描述,可以考虑一下有何问题。
在这个代码中,还有一个要注意的地方,就it.remove(),因为某个key在处理过后要删除,否则,这个key将一直处于active状态。
Java NIO的多路复用及reactor的更多相关文章
- java NIO的多路复用及reactor模式【转载】
关于java的NIO,以下博客总结的比较详细,适合初学者学习(http://ifeve.com/java-nio-all/) 下面的文字转载自:http://www.blogjava.net/hell ...
- Java多线程:Linux多路复用,Java NIO与Netty简述
JVM的多路复用器实现原理 Linux 2.5以前:select/poll Linux 2.6以后: epoll Windows: IOCP Free BSD, OS X: kqueue 下面仅讲解L ...
- 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor
开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...
- java NIO中的Reactor相关知识汇总 (转)
一.引子 nio是java的IO框架里边十分重要的一部分内容,其最核心的就是提供了非阻塞IO的处理方式,最典型的应用场景就是处理网络连接.很多同学提起nio都能说起一二,但是细究其背后的原理.思想往往 ...
- I/O模型之四:Java 浅析I/O模型(BIO、NIO、AIO、Reactor、Proactor)
目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...
- 从I/O多路复用到Netty,还要跨过Java NIO包
本文是Netty系列第4篇 上一篇文章我们深入了解了I/O多路复用的三种实现形式,select/poll/epoll. 那Netty是使用哪种实现的I/O多路复用呢?这个问题,得从Java NIO包说 ...
- Java NIO 与 基于reactor设计模式的事件处理模型
Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内 ...
- Java网络编程和NIO详解2:JAVA NIO一步步构建IO多路复用的请求模型
Java网络编程与NIO详解2:JAVA NIO一步步构建IO多路复用的请求模型 知识点 nio 下 I/O 阻塞与非阻塞实现 SocketChannel 介绍 I/O 多路复用的原理 事件选择器与 ...
- Java NIO学习与记录(八): Reactor两种多线程模型的实现
Reactor两种多线程模型的实现 注:本篇文章例子基于上一篇进行:Java NIO学习与记录(七): Reactor单线程模型的实现 紧接着上篇Reactor单线程模型的例子来,假设Handler的 ...
随机推荐
- OpenCV:Mat元素访问方法、演出、代码的复杂性和安全性分析
欢迎转载.尊重原创,因此,请注明出处: http://blog.csdn.net/bendanban/article/details/30527785 本文讲述了OpenCV中几种訪问矩阵元素的方法, ...
- MS Open Tech 技术团队构建可靠的Windows版Redis
可靠的Windows版Redis 副标题: 评论更精彩,教你怎么解决64位Windows版Redis狂占C盘的问题. MS Open Tech 技术团队最近花了很多时间来测试最新构建的Windows版 ...
- 64位操作系统下用Microsoft.Jet.OLEDB.4.0出现未注册错误
在WIN7 64位下用Microsoft.Jet.OLEDB.4.0方法访问数据库Access,出现未注册错误 如果是要建立64位的应用程序 1.Microsoft Access Database E ...
- 解决UnicodeEncodeError: 'ascii' codec can't encode characters in position 问题(转)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 8-11: ordinal not in range(128 ...
- php中国的垃圾问题
header这条线加,这是解决中国乱码的问题. 版权声明:本文博主原创文章,博客,未经同意不得转载.
- 开始的iOS编程之前的准备
原地址:http://www.appcoda.com/what-you-need-to-begin-ios-programming/ 1.准备一台苹果设备 这段基本是废话,我就不翻译了,IOS开发你懂 ...
- navicat如何导入sql文件
工具--数据的传输--文件 版权声明:本文博客原创文章,博客,未经同意,不得转载.
- VB6基本数据库应用(五):数据的查找与筛选
同系列的第五篇,上一篇在:http://blog.csdn.net/jiluoxingren/article/details/9633139 数据的查找与筛选 第4篇发布到现在已经过了4天,很抱歉,学 ...
- java 正则表达式提取html纯文本
本文来自我的个人博客: java 正则表达式提取html纯文本 做内容的大家都知道,从html中直接提取纯文本是一个非常大的问题.现将我做的正则匹配贴上: import java.util.regex ...
- 《R实战》读书笔记三
第二章 创建数据集 本章概要 1探索R数据结构 2使用数据编辑器 3数据导入 4数据集标注 本章所介绍内容概括例如以下. 两个方面的内容. 方面一:R数据结构 方面二:进入数据或者导入数据到数据结构 ...