《Java EE 7精粹》—— 2.5 非阻塞I/O

2.5 非阻塞I/O

Servlet 3.0允许异步请求处理,但只允许传统的I/O,这限制了应用程序的可扩展性。在典型应用中,在while循环中读取ServletInputStream:

如果传入的数据被阻塞或者数据流慢于服务器的读取,那么服务器线程就要等待数据。如果数据被写入到ServletOutputStream,同样也可能发生这样的等待。这限制了Web容器的可扩展性。

非阻塞I/O允许开发人员在有可读的数据时执行读操作或者在有写入的数据时执行写操作。这不仅增加了Web容器可伸缩性,也增加了可以同时处理的连接数量。非阻塞I/O只能用于异步请求处理的Servlet、Servlet过滤器和升级处理。

Servlet 3.1通过引入两个新的接口实现了非阻塞I/O:ReadListener和WriteListener。这些接口定义了回调方法,用于在有可读或者可写内容时被调用而不阻塞线程。

在本例中doGet()方法需要重写:

调用setXXXListener方法表明使用非阻塞I/O来代替传统的I/O。

ReadListener有以下三个回调方法。

  • 每当非阻塞的可读数据有效时,onDataAvailable()回调方法被调用。
  • 每当当前请求的数据读取完全时,onAllDataRead()回调方法被调用。
  • 如果请求处理过程中发生错误,onError()回调方法被调用:

在这段代码中,onDataAvailable()回调方法被调用时数据可以不受阻塞地读取。ServletInputStream.isReady()方法用于检查数据可以被读取而不会阻塞,然后将数据读出。context.complete()方法在onAllDataRead()方法和onError()方法中被调用,以发出完成读取数据的信号。ServletInputStream.isFinished()方法可被用于检查非阻塞I/O读取的状态。

在ServletIntputStream中最多可以注册一个ReadListener。

WriteListener有以下两个回调方法。

  • 每当非阻塞的可写数据有效时,onWritePossible()回调方法被调用。
  • 如果请求处理过程中发生错误,onError()回调方法被调用。

在ServletOutputStream中最多可以注册一个WriteListener。ServletOutputStream. canWrite()方法是个新的方法,用于检查非阻塞数据是否可写。

时间: 2024-10-25 09:51:21

《Java EE 7精粹》—— 2.5 非阻塞I/O的相关文章

《Java EE 7精粹》—— 导读

前言 Java EE 7平台建立在以前的版本之上,侧重于提高生产力和拥抱HTML5.本书面向的是想快速概览这个平台和回来复习基础知识的读者. 本书提供了Java EE 7平台中关键规范的概述(每章一个规范).本书绝不是一本介绍不同规范中每一个概念的详尽指南或教程,而是通过简单的代码示例来解释不同规范的主要概念.阅读本书,无需具备Java EE平台早期版本的知识,但你需要对Java有一些基本了解,以便理解代码. 这本书的重要部分来自<Java EE 6 Pocket Guide>(O'Reill

【转】聊聊java高并发系统之异步非阻塞

在做电商系统时,流量入口如首页.活动页.商品详情页等系统承载了网站的大部分流量,而这些系统的主要职责包括聚合数据拼装模板.热点统计.缓存.下游功能降级开关.托底数据等等.其中聚合数据需要调用其它多个系统服务获取数据.拼装数据/模板然后返回给前端,聚合数据来源主要有依赖系统/服务.缓存.数据库等:而系统之间的调用可以通过如http接口调用(如HttpClient).SOA服务调用(如dubbo.thrift)等等.   在Java中,如使用Tomcat,一个请求会分配一个线程进行请求处理,该线程负

《Java EE 7精粹》—— 1.2 可交付成果

1.2 可交付成果 Java EE 7平台是遵从JCP 2.9作为JSR 342而开发的.JCP过程对每一个JSR定义了以下三个主要可交付成果. 1.2.1 规范(Specification) 描述了被提议的组件及其功能的一份正式的文件. 1.2.2 参考实现(RI) 对被提议的规范的二进制实现.参考实现有助于确保被提议的规范能以一个二进制形式实现,并为规范过程提供不断的反馈. Java EE的参考实现建立在GlassFish社区中. 1.2.3 技术兼容包(TCK) 用于验证参考实现是否符合被

《Java EE 7精粹》—— 3.3 复合组件

3.3 复合组件 JSF使用Facelets的功能和资源的处理来定义复合组件,定义在Facelets标记文件中的一个或多个JSF组件组成了一个复合组件.这个.xhtml文件存储在资源库中,可以从页面的任意区域创建一个可重用的组件. 复合组件在定义页面中定义,在使用页面中使用.定义页面使用定义元数据(或参数),使用<cc:implementation>定义实现,其中cc是http://xmlns.jcp.org/jsf/composite/命名空间的前缀.JSF规范的未来版本可能会放宽对指定元数

《Java EE 7精粹》—— 第3章 JSF 3.1 Facelets

第3章 JSF JSF是基于Java的Web应用程序开发的服务器端用户界面(UI)框架.使用JSF可以实现: 使用遵循模型-视图-控制器(MVC)设计模式的可重用的UI组件集合来创建网页. 绑定组件到服务器端模型,允许UI与应用程序数据双向移动. 处理UI事件响应和模型交互中的页面导航. 管理跨服务器请求的UI组件状态. 提供从客户端生成的事件到服务器端应用程序代码的简单模型. 轻松地构建和重用自定义UI组件. JSF应用程序包括: 置于UI组件的布局中的一组网页. 一组托管的Bean,包括绑定

《Java EE 7精粹》—— 3.5 Ajax

3.5 Ajax JSF原生支持添加Ajax功能到网页.JSF允许局部视图的处理,其中只有视图中的一些组件用于处理该响应.JSF可以摘选页面上的某些组件,渲染局部页面,而不是整个页面. 有以下两种方法可以启用这种支持. 以编程方式使用JavaScript资源. 以声明的方式使用f:ajax组件. 编程方式的Ajax集成是通过资源处理机制启用的.jsf.js是在javax.faces库中预定义的资源.该资源包含用于Ajax和JSF页面交互的JavaScript API.可以在页面中使用output

《Java EE 7精粹》—— 2.4 异步支持

2.4 异步支持 服务器端的资源是昂贵的,应谨慎使用.试想一个Servlet不得不等待的场景:连接池中提供一个有效的JDBC连接,接收JMS消息或从文件系统中读取资源.等待"长时间运行"的过程完全返回,阻塞了线程(等待,坐着,什么也不做),服务器资源没有得到最佳的使用.这正是异步处理的用武之地.服务器可以异步执行,在等待长时间运行的过程完成期间,控制(或线程)被返回到容器来执行其他任务.请求处理在长期运行的过程返回之后,在同一个线程继续执行,也可以将长期运行的过程分派给一个新的资源.一

《Java EE 7精粹》—— 2.6 Web Fragment

2.6 Web Fragment 包含在库或框架JAR包的META-INF目录中的一个web fragment片段是部分或全部在web.xml文件中.如果这个框架绑定在WEB-INF/lib目录中,容器会选择和配置框架,而无需开发人员显示地做到这一点. Web Fragment可以包括几乎所有web.xml中指定的元素.然而,其顶级元素必须是web-fragment,并且相应的文件必须命名为webfragment.xml.这将允许Web应用程序逻辑分区: 开发人员可以指定在web.xml和web

《Java EE 7精粹》—— 2.3 事件监听器

2.3 事件监听器 事件监听器提供对ServletContext.HttpSession和ServletRequest对象生命周期的回调事件.这些监听器实现了支持上述对象状态变化事件通知的接口类.每个类可以通过@WebListener注解定义或者在web.xml中声明,抑或通过ServletContext. addListener()方法注册.一个典型的监听器例子是以编程方式注册一个额外的Servlet而没有明确要求程序员这样做,或者应用程序级别的数据库连接的初始化和恢复. 可以有多个监听器类来