- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
简介:?Java 技术平台早就应该提供非阻塞 I/O 机制了。幸运的是,Merlin(JDK 1.4)有一根几乎在各个场合都适用的魔杖,而解除阻塞了的 I/O 的阻塞状态正是这位魔术师的专长。软件工程师 Aruna Kalagnanam 和 Balu G 介绍了 Merlin 的新 I/O 包 ― java.nio(NIO)― 的这种非阻塞功能,并且用一个套接字编程示例向您展示 NIO 能做些什么。请单击本文顶部或底部的 讨论,在 讨论论坛与作者及其他读者分享您关于本文的心得。
服务器在合理的时间之内处理大量客户机请求的能力取决于服务器使用 I/O 流的效率。同时为成百上千个客户机提供服务的服务器必须能够并发地使用 I/O 服务。Java 平台直到 JDK 1.4(也就是 Merlin)才支持非阻塞 I/O 调用。用 Java 语言写的服务器,由于其线程与客户机之比几乎是一比一,因而易于受到大量线程开销的影响,其结果是既导致了性能问题又缺乏可伸缩性。
为了解决这个问题,Java 平台的最新发行版引入了一组新的类。Merlin 的 java.nio 包充满了解决线程开销问题的技巧,包中最重要的是新的 SelectableChannel 类和 Selector 类。 通道(channel)是客户机和服务器之间的一种通信方式。 选择器(selector)与 Windows 消息循环类似,它从不同客户机捕获各种事件并将它们分派到相应的事件处理程序。在本文,我们将向您展示这两个类如何协同工作,从而为 Java 平台创建非阻塞 I/O 机制。
Merlin 之前的 I/O 编程
我们将从考察基础的、Merlin 之前的服务器-套接字(server-socket)程序开始。在 ServerSocket 类的生存期中,其重要功能如下:
接受传入连接
从客户机读取请求
为请求提供服务
我们来考察一下以上每一个步骤,我们用代码片段来说明。 首先,我们创建一个新的 ServerSocket :
ServerSocket s = new ServerSocket();
接着,我们要接受传入调用。这里,调用 accept() 应该可以完成任务,但其中有个小陷阱您得当心:
Socket conn = s.accept( );
对 accept() 的调用将一直阻塞,直到服务器套接字接受了一个请求连接的客户机请求。一旦建立了连接,服务器就使用 LineNumberReader 读取客户机请求。因为 LineNumberReader 要到缓冲区满时才成批地读取数据,所以这个调用在读时阻塞。 下面的片段显示了工作中的 LineNumberReader (阻塞等等)。
InputStream in = conn.getInputStream();
InputStreamReader rdr = new InputStreamReader(in);
LineNumberReader lnr = new LineNumberReader(rdr);
Request req = new Request();
while (!req.isComplete() )
{
String s = lnr.readLine();
req.addLine(s);
}
InputStream.read() 是另一种读取数据的方式。不幸的是, read 方法也要一直阻塞到数据可用为止, write 方法也一样,。
图 1 描绘了服务器的典型工作过程。黑体线表示处于阻塞的操作。
图 1. 典型的工作中的服务器
在 JDK 1.4 之前,自由地使用线程是处理阻塞问题最典型的办法。但这个解决办法会产生它自己的问题 ― 即线程开销,线程开销同时影响性能和可伸缩性。不过,随着 Merlin 和 java.nio 包的到来,一切都变了。
在下面的几个部分中,我们将考察 java.nio 的基本思想,然后把我们所学到的一些知识应用于修改前面描述的服务器-套接字示例。
回页首
反应器模式(Reactor pattern)
NIO 设计背后的基石是反应器设计模式。 分布式系统中的服务器应用程序必须处理多个向它们发送服务请求的客户机。然而,在调用特定的服务之前,服务器应用程序必须将每个传入请求多路分用并分派到各自相应的服务提供者。反应器模式正好适用于这一功能。它允许事件驱动应用程序将服务请求多路分用并进行分派,然后,这些服务请求被并发地从一个或多个客户机传送到应用程序。
反应器模式的核心功能
将事件多路分用
将事件分派到各自相应的事件处理程序
反应器模式与观察者模式(Observer pattern)在这个方面极为相似:当一个主体发生改变时,所有依属体都得到通知。
文档评论(0)