快速业务通道

Servlet API和NIO: 最终组合在一起 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-20
基于 Java 的客户机/服务器应用程序。这里,我们让一个线程单独负责处理非阻塞通道(生产者),让另一个线程单独负责把数据作为流消费(消费者)。管道也为应用程序服务器解决了非阻塞 I/O 问题,因为 servlet 在消费 I/O 时将采用阻塞语义。

示例服务器

示例服务器展示了 Servlet API 和 NIO 不兼容的生产者/消费者解决方案。该服务器与 Servlet API 非常相似,可以为成熟的基于 NIO 应用程序服务器提供 POC (proof of concept),是专门编写来衡量 NIO 相对于标准 Java I/O 的性能的。它处理简单的 HTTP get 请求,并支持来自客户机的 Keep-Alive 连接。这是重要的,因为多路复用 I/O 只证明在要求服务器处理大量打开的 scoket 连接时是有意的。

该服务器被分成两个包: org.sse.server 和 org.sse.http 包中有提供主要 服务器 功能的类,比如如下的一些功能:接收新客户机连接、阅读消息和生成工作线程以处理请求。http 包支持 HTTP 协议的一个子集。详细阐述 HTTP 超出了本文的范围。

现在让我们来看一下 org.sse.server 包中一些最重要的类。

Servlet API和NIO: 最终组合在一起(2)

时间:2011-01-26 IBM Taylor Cowan

Server 类

Server 类拥有多路复用循环 —— 任何基于 NIO 服务器的核心。在清单 1 中,在服务器接收新客户机或检测到正把可用的字节写到打开的 socket 前, select() 的调用阻塞了。这与标准 Java I/O 的主要区别是,所有的数据都是在这个循环中读取的。通常会把从特定 socket 中读取字节的任务分配给一个新线程。使用 NIO 选择器事件驱动方法,实际上可以用单个线程处理成千上万的客户机,不过,我们还会在后面看到线程仍有一个角色要扮演。

每个 select() 调用返回一组事件,指出新客户机可用;新数据准备就绪,可以读取;或者客户机准备就绪,可以接收响应。server 的 handleKey() 方法只对新客户机( key.isAcceptable() )和传入数据 ( key.isReadable() ) 感兴趣。到这里,工作就结束了,转入 ServerEventHandler 类。

清单 1. Server.java 选择器循环

public void listen() {    SelectionKey key = null;    try {     while (true) {       selector.select();       Iterator it = selector.selectedKeys().iterator();       while (it.hasNext()) {        key = (SelectionKey) it.next();        handleKey(key);        it.remove();       }     }    } catch (IOException e) {     key.cancel();    } catch (NullPointerException e) {     // NullPointer at sun.nio.ch.WindowsSelectorImpl, Bug: 4729342     e.printStackTrace();    } }

ServerEventHandler 类

ServerEventHandler 类响应服务器事件。当新客户机变为可用时,它就实例化一个新的 Client 对象,该对象代表了那个客户机的状态。数据是以非阻塞方式从通道中读取的,并被写到 Client 对象中。ServerEventHandler 对象也维护请求队列。为了处理(消费)队列中的请求,生成了不定数量的工作线程。在传统的生产者/消费者方式下,为了在队列变为空时线程会阻塞,并在新请求可用时线程会得到通知,需要写 Queue 。

为了支持等待的线程,在清单 2 中已经重写了 remove() 方法。如果列表为空,就会增加等待线程的数量,并阻塞当前线程。它实质上提供了非常简单的线程池。

清单 2. Queue.java

public class Queue extends LinkedList {   private int waitingThreads = 0;   public synchronized void insert(Object obj)   {   addLast(obj);   notify();   }   public synchroni

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号