Servlet3.0: 简介AsyncContext
每个请求来到Web容器,Web容器会为其分配一条执行绪来专门负责该请求,直到回应完成前,该执行绪都不会被释放回容器。 执行绪会耗用系统资源,若有些请求需要长时间处理(例如长时间运算、等待某个资源),就会长时间占用执行绪,若这类的请求很多,许多执行绪都被长时间占用,对于系统就会是个效能负担,甚至造成应用程式的效能瓶颈。
基本上一些需长时间处理的请求,通常客户端也较不在乎请求后要有立即的回应,若可以,让这类请求先释放容器分配给该请求的执行绪,让容器可以有机会将执行绪资源分配给其它的请求,可以减轻系统负担。 原先释放了容器所分配执行绪的请求,其回应将被延后,直到处理完成(例如长时间运算完成、所需资源已获得)再行对客户端的回应。
在Servlet 3.0中,在ServletRequest上提供了 startAsync( )方法:
- AsyncContext startAsync() throws java.lang.IllegalStateException;
- AsyncContext startAsync(ServletRequest servletRequest,
- ServletResponse servletResponse)
- throws java.lang.IllegalStateException
这两个方法都会传回AsyncContext介面的实作物件,前者会直接利用原有的请求与回应物件来建立AsyncContext ,后者可以让你传入自己建立的请求、回应包裹物件。 在呼叫了startAsync()方法取得AsyncContext物件之后,这次的回应会被延后,并释放容器所分配的执行绪。
你可以透过AsyncContext的getRequest() 、 getResponse()方法取得请求、回应物件,此次对客户端的回应将暂缓至呼叫AsyncContext的complete()方法或dispatch()为止,前者表示回应完成,后者表示将回应调派给指定的URL 。
若要能呼叫ServletRequest的startAsync()使用AsyncContext,你的 Servlet 必须能支援非同步处理,如果使用@WebServlet来标注,则可以设定其asyncSupported为true 。 例如:
- @WebServlet(urlPatterns = "/some.do", asyncSupported = true )
- public class AsyncServlet extends HttpServlet {
- ...
如果使用web.xml设定Servlet,则可以设定<async-supported>标签为true :
- ...
- <servlet>
- <servlet-name>AsyncServlet</servlet-name>
- <servlet-class>cc.openhome.AsyncServlet</servlet-class>
- <async-supported>true</async-supported>
- </servlet>
- ...
如果Servlet将会非同步处理,若其前端有过滤器,则过滤器亦需标示其支援非同步处理,如果使用@WebFilter ,同样是可以设定其asyncSupported为true 。 例如:
- @WebFilter(urlPatterns = "/some.do", asyncSupported = true )
- public class AsyncFilter implements Filter{
- ...
如果使用web.xml设定过滤器,则可以设定<async-supported>标签为true :
- ...
- <filter>
- < filter -name>AsyncFilter</ filter -name>
- < filter -class>cc.openhome.AsyncFilter</ filter -class>
- <async-supported>true</async-supported>
- </ filter >
- ...
底下示范一个非同步处理的例子,对于进来的请求,Servlet会取得其AsyncContext ,并释放容器所分配的执行绪,回应被延后,对于这些被延后回应的请求,建立一个Runnable的物件,并将其排入一个执行绪池(Thread pool),执行绪池的执行绪数量是固定的,让这些必须长时间处理的请求,在这些有限数量的执行绪中完成,而不用每次请求都占用容器所分配的执行绪。
- package cc.openhome;
- import java.io.*;
- import java.util.concurrent.*;
- import javax.servlet.*;
- import javax.servlet.annotation.*;
- import javax.servlet.http.*;
- @WebServlet(name="AsyncServlet", urlPatterns={"/async.do"},
- asyncSupported = true )
- public class AsyncServlet extends HttpServlet {
- // 执行绪池
- private ExecutorService executorService = Executors.newFixedThreadPool(10);
- protected void processRequest(HttpServletRequest request,
- HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html; charset=UTF8");
- AsyncContext ctx = request.startAsync();
- executorService.submit(new AsyncRequest(ctx));
- }
- @Override
- protected void doGet(HttpServletRequest request,
- HttpServletResponse response)
- throws ServletException, IOException {
- processRequest(request, response);
- }
- @Override
- protected void doPost(HttpServletRequest request,
- HttpServletResponse response)
- throws ServletException, IOException {
- processRequest(request, response);
- }
- @Override
- public void destroy() {
- executorService.shutdown();
- }
- }
AsyncRequest是个实作Runnable的类别,其模拟了长时间处理:
- package cc.openhome;
- import java.io.PrintWriter;
- import javax.servlet.AsyncContext;
- public class AsyncRequest implements Runnable {
- private AsyncContext ctx;
- public AsyncRequest( AsyncContext ctx ) {
- this.ctx = ctx;
- }
- @Override
- public void run() {
- try {
- // 模拟长时间的处理
- Thread.sleep(10000);
- PrintWriter out = ctx.getResponse() .getWriter();
- out.println("久等了...XD");
- // 这边才真正送出回应
- ctx.complete();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
Servlet3.0: 简介AsyncContext的更多相关文章
- Spring注解开发系列VII --- Servlet3.0
Servlet3.0简介 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用 ...
- Servlet3.0的异步
servlet之前的操作同时同步的,就是按照这样的一个流程来走的: 1.请求根据一个路径路由到一个servlet中, 2.servlet获取一系列的参数 3.执行一系列的逻辑(花费时间所占的比重也更大 ...
- Servlet3.0中Servlet的使用
目录 1.注解配置 2.异步调用 3.文件上传 相对于之前的版本,Servlet3.0中的Servlet有以下改进: l 支持注解配置. l 支持异步调用. l 直接有对文件上传的支持. 在这篇 ...
- Servlet3.0新特性
1 Servlet3.0新特性概述 使用要求:MyEclipse10.0或以上版本,发布到Tomcat7.0或以上版本,创建JavaEE6.0应用! Servlete3.0的主要新特性如下三部分: 使 ...
- Servlet3.0的新特性
注意:Servlet3.0的项目一定要使用Tomcat7.0才能看到效果!! 1.新增标注支持 在Servlet3.0的部署描述文件web.xml的顶层标签<web-app>中有一 ...
- [译]servlet3.0与non-blocking服务端推送技术
Non-blocking(NIO)Server Push and Servlet 3 在我的前一篇文章写道如何期待成熟的使用node.js.假定有一个框架,基于该框架,开发者只需要定义协议及相关的ha ...
- Servlet3.0新特性使用详解
可插拔的Web框架 几乎所有基于Java的web框架都建立在servlet之上.现今大多数web框架要么通过servlet.要么通过Web.xml插入.利用标注(Annotation)来定义servl ...
- Servlet3.0新特性(从注解配置到websocket编程)
Servlet3.0的出现是servlet史上最大的变革,其中的许多新特性大大的简化了web应用的开发,为广大劳苦的程序员减轻了压力,提高了web开发的效率.主要新特性有以下几个: 引入注解配置 支持 ...
- Java自学手记——servlet3.0新特性
servlet3.0出来已经很久了,但市场上尚未普遍应用,servlet3.0有三个比较重要的新特性:使用注解来代替配置文件,异步处理以及上传组件支持. 支持servlet3.0的要求:MyEclip ...
随机推荐
- 1.6(学习笔记)Session
一. Session简介 Session是用于解决HTTP无状态问题,HTTP协议本身是没有状态的, 就类似一个没有记性的商人,每次只交易当前的货物,交易完后就忘记了 以前的交易历史.我们和商人交易时 ...
- 十. 图形界面(GUI)设计12.滚动条
滚动条(JScrollBar)也称为滑块,用来表示一个相对值,该值代表指定范围内的一个整数.例如,用Word编辑文档时,编辑窗右边的滑块对应当前编辑位置在整个文档中的相对位置,可以通过移动选择新的编辑 ...
- Scala实战高手****第11课:Scala面向接口彻底实战和Spark源码鉴赏
第一点: scala的接口trait中所有方法可以都被实现!! 这种情况一般会是一种工具方法的集合,例如接口 Logging! scala 多种继承用extends ... with .... 在老 ...
- 上传ipa文件时报错 Your account already has a valid iOS distribution certificate
这个问题是因为你本机的生产证书是在别人的电脑上创建的,所以才会提示你已经有一个有效的生产证书,但是没有安装到本地:
- 上手 Webpack ? 这篇就够了!
JavaSript 模块化打包已混迹江湖许久.2009年,RequireJS 就提交了它的第一个版本,Browserify 接踵而至,随后其他打包工具也开始大行其道.最终,Webpack 从其中脱颖而 ...
- php新浪云链接mysql与storage
1.首先要有一个新浪云服务器 2.链接数据库获取数据 mysql CREATE TABLE Persons(FirstName varchar(255),LastName varchar(255)); ...
- Easyui的numberbox无法输入以0开头的数字编号(转载)
1.问题 项目中碰到这样一个问题,Easyui的numberbox在输入数字编号的时候不能以0开头 在我输入以0开头的数字编号后,离开输入框的时候,那个前缀0就自动去掉了. 接下来,我们查看API说明 ...
- Python图像处理(8):边缘检測
快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 此前已经得到了单个区域植株图像,接下来似乎应该尝试对这些区域进行分类识别.通过外形和叶脉进行植物种 ...
- java源码阅读LinkedList
1类签名与注释 public class LinkedList<E> extends AbstractSequentialList<E> implements List< ...
- golang中的那些坑之迭代器中的指针使用
今天在编写代码的时候,遇到了一个莫名其妙的错误,debug了半天,发现这是一个非常典型且易犯的错误.记之 示例代码: package main import "fmt" type ...