Servlet3.0 异步处理机制

在早前版本的Servlet规范中,若是Servlet做为控制器调用了一个较耗时的业务方法,那么Servlet必须等到业务方法彻底返回以后才生成响应,这使得Servlet对业务方法的调用变成一种阻塞式的调用,从而致使运行效率下降。 html

Servlet3.0规范引入了异步处理来解决这个问题,异步处理容许Servlet从新发起一条新线程去调用较耗时的业务方法,这样就可避免等待。该异步机制是经过AsyncContext类来处理的,Servlet可经过ServletRequest的以下两个方法开启异步调用、建立AsyncContext对象: java

一、AsyncContext startAsync() session

   二、AsyncContext startAsync(ServletRequest,ServletResponse) 异步

重复调用上面的方法将获得同一个AyncContext对象,AyncContext对象表明异步处理的上下文,它提供了一些工具方法,能够完成设置异步调用的超时时长,dispatch用于请求,启动后台线程、获取request response对象等功能 jsp

Code demo: async

@WebServlet(urlPatterns="/async",asyncSupported=true) ide

public class AsyncServlet extends HttpServlet 工具

{ this

   @Override url

   public void doGet(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletException{

   response.setContentType("text/html,charset=GBK");

   PrinterWriter out = response.getWriter();

   out.println("<title>异步</tilte>");

   out.println("进入Servlet的时间:"+new java.util.Date()+".<br/>");

   out.flush();

  // 建立AsyncContext,开始异步调用

  AsyncContext actx = request.startAsync();

  // 设置异步调用的超时时长

  actx.setTimeout(30*1000);

  // 启动异步调用的线程

  actx.start(new Executor(actx));

  out.println("结束Servlet的时间:"+new java.util.Date()+".<br />");

  out.flush();

   }

}

 

Excutor.java:

public class Executor implements Runnable

{

   pirvate AyncContext actx = null;

  public Executor(AsyncContext){   this.actx = actx; }

 public void run()

{

   try{

      // 等待10秒,模拟业务方法的执行

    Thread.sleep(10 * 1000);

    ServletRequest request = actx.getRequest();

    List<String> books = new ArrayList<>();

    books.add("Thinking in  java");

   books.add("Effective java");

   books.add("Core Java");

request.setAttribute("books",books);

actx.dispatch("/async.jsp");

     }catch(Exception e){   e.printStackTrace();    }

    }

}

该线程执行体内让线程暂停10秒钟来模拟调用耗时的业务方法,最后调用 AsyncContext的dispatch方法把请求dispatch到指定的JSP页面。

被 异步请求dispatch的目标页面须要指定session="false",代表该页面不会从新建立 session。

async.jsp:

<% page contentType="text/html;charset=GBK" language="java" session="false"%>

<% taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<ul>

   <c:forEach items="${books}" var ="book">

      <li>${book}</li>

  </c:forEach>

</ul>

<%

   out.println("调用业务结束时间:"+new java.util.Date());

  request.getAsyncContext().complete();

%>

相关文章
相关标签/搜索