异步处理功能可以节约容器线程。此功能的作用是释放正在等待完成的线程,是该线程能够被另一请求所使用。
要编写支持异步处理的 Servlet 或者过虑器,需要设置 asyncSupported 属性为 true。
@WebServlet(asyncSupported=true ... ) @WebFilter(asyncSupported=true ... )
当然也可以在部署描述符(web.xml)里面指定这个描述符。
<servlet> <servlet-name>AsyncServlet</servlet-name> <servlet-class>servlet.MyAsyncServlet</servlet-class> <async-supported>true</async-supported> </servlet>
编写异步Servlet
(1)调用 ServletRequest 中的 startAsync 方法,该方法返回一个 AsyncContext 实例对象。
(2)调用 AsyncContext 的 setTimeout(),传递容器等待任务完成的超时时间的毫秒数。若不设置容器采用默认的超时时间,如果任务未能在指定的超时时间内完成,将会抛出一个超时异常。
(3)调用 asyncContext.start(),传递一个 Runnable 来执行一个长时间运行的任务。
(4)调用 Runnable 的 asyncContext.complete() 或 asyncContext.dispatch()方法来完成任务。
一个简单的异步调度的Servlet
package app11a; import java.io.IOException; import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "AsyncDispatchServlet", urlPatterns = { "/asyncDispatch" }, asyncSupported = true ) public class AsyncDispatchServlet extends HttpServlet { private static final long serialVersionUID = 1L; public AsyncDispatchServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { final AsyncContext asyncContext = request.startAsync(); // 调用 ServletRequest 中的 startAsync 方法 request.setAttribute("mainThread", Thread.currentThread().getName()); asyncContext.setTimeout(5000); // 调用 AsyncContext 的 setTimeout(),传递容器等待任务完成的超时时间的毫秒数 asyncContext.start(new Runnable() { // 调用 asyncContext.start(),传递一个 Runnable 来执行一个长时间运行的任务。 @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } request.setAttribute("workerThread", Thread.currentThread().getName()); asyncContext.dispatch("/threadNames.jsp"); // 调用 Runnable 的 asyncContext.complete() 或 asyncContext.dispatch()方法来完成任务 } }); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
<!-- threadNames.jsp --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Asynchronous servlet</title> </head> <body> Main thread: ${mainThread } <br /> Worker thread: ${workerThread } </body> </html>