1 概述
在Servlet Api 3.0版本之前,Servlet容器会为每个Http请求都分配一个工作线程。即对每一次Http请求,Servlet容器都会从主线程池中取出一个空闲的工作线程。这个空闲的工作线程从头到尾的负责处理请求。如果某个Http请求耗时很长,那么这个工作线程就会长时间被占用,只有当这个Http请求完成了响应,才会被释放。
如果访问量特别大的话,线程池中的许多工作线程都会被占用大量的时间,这会相当影响我们服务器的访问性能。为了解决这种问题,从Servlet Api 3.0开始就引入了异步处理机制。
2 异步处理的思路
Servlet异步处理得机制,Servlet从HttpServletRequest对象中获取一个AsyncContext对象,该对象表示异步处理的上下文。AnsynContext对象把当前请求的任务传给了一个新的线程,由这个线程来完成对请求的处理并向客户端响应结果。
3,异步处理的操作步骤
1,如果是使用注解方式配置的Servlet,那么设置@WebServlet注解的asyncSupport属性设置为true。如果是用xml配置方式配置的Servlet我们使用如下代码配置(<async-supported>true</async-supported>):
<servlet>
<servlet-name>RequestInfoServlet</servlet-name>
<servlet-class>com.vgixt.helloworld.servlet.RequestInfoServlet</servlet-class>
<async-supported>true</async-supported>
</servlet>
2,在Servlet类的服务方法中,通过ServletRequest对象的startAsync()方法来获取AsyncContext对象。
AnyncContext接口为异步处理提供了上下文,它有如下一些方法:
- setTimeout(long timeout):设置异步线程处理请求的超时时间,单位是毫秒。表示这个异步任务必须在多少时间内完成。
- start(Runnable run):启动一个异步线程,执行对应的任务
- addListener(AsyncListener listener):添加一个异步监听器
- complete():告诉Servlet容器完成任务返回响应结果。
- dispatch(String path):把请求派发给参数path指定的Web组件
- getRequest():获得当前上下文中ServletRequest对象。
- getResponse():获得当前上下文中的ServletResponse对象。
3 调用AsyncContext对象的setTimeout(long timeout)来设置异步线程的超时时间,当然这个你也可以不用设置
4 启动一个异步任务来执行相关的请求
5 调用AsyncContext对象的complete()方法来告诉Servlet容器已经完成任务,或者调用dispatch()把请求派发给其他组件。
运行流程图:
5,异步处理的实例
package com.vgxit.servlet.servlet;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet