1. 程式人生 > >非同步Servlet和非同步過慮器

非同步Servlet和非同步過慮器

非同步處理功能可以節約容器執行緒。此功能的作用是釋放正在等待完成的執行緒,是該執行緒能夠被另一請求所使用。

要編寫支援非同步處理的 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>

傳送最新進度更新的非同步servlet