维普资讯 http://www.cqvip.com 2∞6年3月 重庆文理学院学报(自然科学版) M4r。.20o6 第5卷第1期 Journal of Chongqing University of Arts and Sciences(Nature Sciences Edition) Vo1.5 No.1 解析Java中的阻塞I/O与非阻塞I/O控制 龚黔芬 (重庆工商大学计算机科学与信息工程学院,重庆40oo67) [摘 要】分析了新、旧I/0 API工作原理及其可伸缩性方面的差异,阐述了如何用选择器通道 技术让SocketChannel工作在非阻塞I/O模式下,以实现服务器与客户端无阻塞的、流畅的数据 读写。使服务器能在较小的系统开销情况下更有效地、并发地为大量客户机提供服务,提升系 统性能. [关键词]阻塞I/O;非阻塞I/0;选择器;通道 [中图分类号]TP393.07[文献标识码]A[文章编号]1671—7538(2006)01—0018—03 IO API的可伸缩性对C/S系统应用有着极其重要的意义.服务器在合理的时间之内处理大量客 户机请求的能力取决于服务器使用I/O流的效率,同时为成百上千个客户机提供服务的服务器必须 能够并发地使用I/O服务;而用早期版本Java语言写的服务器,由于其线程与客户机之比几乎是1:1, 因而易于受到大量线程开销的影响.其结果是既导致了性能问题,系统又缺乏可伸缩性.从J2SE 1.4 版本开始,Java终于有了可伸缩的I/O API,提供了非阻塞I/O模式来完成大量的数据源并行处理.以下 将对传统阻塞模式下I/O的弊端以及新的非阻塞I/O模式的工作原理进行分析. 1 阻塞i/O 1.1单线程模式 在Java平台上处理有关I/O操作的方法通常是:当一个方法需要处理I/O有关事务时,该方法立即被 Java虚拟机设置成等待状态,直到有关I/O操作完成.通常这样的过程称为阻塞I/O,其实现过程如下: 第1步:创建新的SeverSocket. SeverSocket SEV new SeverSocket(portnumber). , 第2步:调用accept()方法准备接收一个客户机的连接,对accept()方法调用将一直阻塞,直到接 收到客户机请求为止. . 第3步:处理用户请求(包括读写输入输出流).在这个过程中也存在阻塞,只有它完成对当前连 接处理后服务器才能接受另一台客户机的请求.(在单线程模式下,如果打开两客户端,会发现一客户 端一直处于等待状态,直到另一客户端处理完后才得到服务器的响应.)同时,网络系统运行时性能瓶 颈通常在I/O,包括对流和文件的操作,read()等候在端El不断续读取传输过来的字节内容.如果读入 本地文件则不需要等待太长时间,但如果从文件服务器或socket连接读取数据的话,那么就要耗费很 长的等待时间.在等待过程中,读取数据的线程将不能做任何事.这种处理方式导致Java处理I/O事 务时性能不佳. . . 1.2 改进模式 + 为了解决上面的问题,可以把每一个Socket和一个线程关联起来.采用这种方法之后,当一个线 程由于I/O相关的任务被阻塞时,另一个线程仍旧能够运行. While(true) [收稿13期]2005—12—20 【作者简介]龚黔芬(1977一).女.重庆市人。助教,主要从事计算机硬件与通讯技术研究 18 维普资讯 http://www.cqvip.com {Socket server=SeverSocket.accpet(); try {new SocketthI℃ad(sever);} } 改进模式引入的问题是生成和管理线程的不经济.每个线程都需要较多的系统资源(内存、栈、 CPU等),频繁的线程操作将会造成系统性能急剧下降.如果用这样的模型建立一个服务器端,来一个 连接开至少2个线程.要是业务负担很大、连接的socket很多的话,会带来相当大的开销,而且扩展性 很差,所以这样的方式是不适合做服务器端的. 2非阻塞I/O 非阻塞I/O作为REACTOR模式的实现,实际上提供了一种事件发生、自我激活、主动通知机制. NIO的非阻塞I/O机制是围绕选择器和通道构建的.通道表示连到一个实体(例如:硬件设备、文件、网 络套接字或者能执行一个或多个不同I/O操作的程序组件)的开放连接.选择器是所有非阻塞技术的 主要对象.它监视着已注册的套接字通道,并序列化服务器需要应答的请求.当一些有意义的事发生 在通道上(如客户端试图连接服务器端或进行读,写操作)时,选择器便会通知应用程序处理请求.通 知的方式是创建一个关键字,这个关键字是SelectionKey类的一个实例.每个关键字都保存着应用程序 的标识及请求的类型(尝试连接(客户端)、尝试连接(服务器端)、读取操作、写入操作). 非阻塞I/O工作原理: 第1步:创建选择器 ServerSocketChannel server=ServerSocketChanne1.open();,,建立通道. server.configureBlocking(false);//将它设置为非阻塞,这样才可以使用Selector. server.socket().bind(new java.net.inetSocketAddress(host,8000));//绑定到服务器端的连接. Selector selector=Selector.open();,,仓0建选择器负责监听所有注册事件(如用户连接、读写). 第2步:通道向选择器订阅自己感兴趣的事件类型,包括OP—ACCEPT,OP—CONNECT, OP—READ,OP—WRITE以完成连接,读写数据. 例如: server.register(selector,SeleetionKey.OP—ACCEPT); 第3步:监视器Selector利用selector()方法监听可以被Selector联系的SelectableChanne1.select()方法 的返回值,表示有多少连接已经做好了I/O操作的准备.如果返回值是0,则表示无读写请求,直接返 回;当一个或多个通道有事件发生时,每个通道相应的SelectionK被放人一个容器,称选中KEY集合.调 用selectedKeys()获得键的集合(Set),生成SelectorKey.它用于区分哪一个通道何时需要处理何种操作, 从这些键获得以前关联的ConnectionX{象,然后调用其读数据处理方法或写数据处理方法.具体调用 哪一个方法操作由连接被注册为读取操作还是写入操作决定.通过遍历集合就可以处理每个Selection Key对象来处理多个数据源. 处理过程如下: for(;;){//Infinite server loop sele6tor.select();//查看是否有新的请求. Set keys=selector.selectedKeys();//获得被发现请求的关键字并一一处理它们. Itemtor i=keys.iterator(); while(i.hasNext()){//遍历集合. SelectionKev kev=(SelectionKey)i.next();/,获得单个I/0请求的关键字. //处理SelectionKey. i.remove();//当一个关键字被处理时。调用remove方法从这组关键字中移出. if(key.isAcceptable()){,,如果是连接请求. eScketChannel client=server.accept(); l9 维普资讯 http://www.cqvip.com //服务器端调用accept方法来查找客户端套接字通道. client.configureBlocking(false);//设置它为非阻隔. + client.register(selector,SelectionKey.0Pl-READ);//注册为019=READ或OP_WRITE continue; } if(key.isReadable()){//当客户端在套接字通道上写数据时选择器将通知服务器. SocketChannel client=(SocketChanne1)key.channel();//接收数据处理. int BUFFER—SIZE=32: ByteBuffer buffer=ByteBuffer.allocate(BUFFER SIZE); try{ client.read(buffer); } } } Selector采用不同的工作方式.通过Selector,我们可以把多个I/O流注册到一个Selector对象上.当 某个流发生I/O活动时,Selector将会通知我们.以这种方式可以只用一个线程读人多个数据源.尽管 Selector不能帮我们读取数据,但它可以监听网络连接请求和越过较慢的通道进行写数据. 3结语 新的Java1.4 I/O体系是实现快速、灵活和可升级的java应用程序的重要的一步.依靠非阻塞套接 字技术,我们可以写一个基于非阻塞套接字的应用程序而不用手工来处理多线程.很多免费邮件系统 采用多线程/多进程技术,在访问量较大的时候非常消耗系统资源,因此这类系统的硬件配置要求往 往非常高.如果邮件系统采用非阻塞技术,比多线程/多进程技术占用更小的系统开销,具有更好的性 能和更高的并发联接数,使系统资源的开销大大降低.同等硬件设备的情况下,系统性能表现更为出 色. [参考文献] [1]JavaResearch.org.J2SE进阶[M].北京:机械工业出版社,2004. [2]彭晨阳.Java实用系统开发指南[M].北京:机械工业出版社,2004. [3]刘广涛,等.基于并发服务嚣模型的邮件系统[J].计算机工程与应用,2005,41(8):114—116 The Analysis of the Blocking I/O Method and Non—Blocking I/0 Method in Java GONG Qian—fen (C.ompu ̄r Sconce and Information Engineering College。Chongq ̄g Technology andBusiness Unlversl ̄/,Chongqing 400067,Ch/na) Abstract:In this paper,the basic principle about the I/O AP1 in Java and the difference of extendence between the Blocking I/O method and Non—Blocking method are expounded.Through Selector and channel technology,we Call manage the Socketchannel working on the Non—Blocking model,which ensured the server to run eficiently fand consume less resources,thus provided the possibility and technical assistance for the server to parallel service .thousands of clients. Key words:Blocking I/O;Non—Blocking I/O;Selector;Channel :20