转自: http://caterpillar.onlyfun.net/Gossip/ServletJSP/AsyncContext.html
原文为繁体版, 通过Google 翻译整理
每个请求来到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使用手册,这里面有详细的api参考,使用很方便
servlet3.0jar下载,非常好用的控制器工具类包,servlet3.0jar下载,非常好用的控制器工具类包,
* @project servlet3.0 * servlet3.0的文件上传 * @date:2012-5-21 *在创建项目的时候首先添加Tomcat7.x的支持,然后把apache-tomcat-7.0.27\conf\web.xml拷贝到项目WEB-INF目录下 *把之前的web.xml覆盖.. 配置...
学习servlet3.0 学习servlet3.0
用servlet3.0异步技术,实现推送信息至客户端的聊天室
基于servlet3.0手写springmvc,实现了IOC和处理器映射器以及处理器映射器功能。
Servlet3.0新特性解析_03_Servlet3.0监听器、过滤器实现方式详解及Servlet的动态注册剖析
servlet 3,jar 包综合;用于javaEE servlet 3.0 开发使用。
个人整理的JavaServlet 3.0的API,按Java6 API的风格整理
Servlet 是 Java EE 规范体系的重要组成部分,也是 Java 开发人员必须具备的基础技能,Servlet 3.0 是 Servlet 规范的最新版本。本文主要介绍了 Servlet 3.0 引入的若干重要新特性,包括异步处理、新增的注解支持、...
servlet3.0.zip
Servlet3.0新特性解析_02_Servlet3.0的异步支持与反向Ajax深入详解Servlet3.0新特性解析_02_Servlet3.0的异步支持与反向Ajax深入详解
本工程用于借助Servlet3.0实现文件上传 本工程编码方式:UTF-8 注意: 1、在上传文件前请在计算机C盘新建一个名为“upload”的文件夹,否则会出现如下异常:java.io.IOException: The temporary upload location [C...
Servlet 3.0 源码文件,可以在myeclipse中查看servlet的代码,方便编程
servlet3.0-demo, 上传文件demo,基于注解开发
servlet3.0相关的包 包含 sevlet servlet-api jstl jstl-impl相关版本的包
非常好的学习Servlet3.0资料。特此共享。
使用maven创建web项目使用servlet3.0工具包 默认编辑器下载的servlet为2.3 使用此工具将变为3.0 不再需要每次手动修改
Servlet 3.0jar包和source包
maven servlet 3.0 eclipse config video