Servlet3.0 support for asynchronous processing

Servlet workflow

Before Servlet 3.0, a major common workflow Servlet roughly as follows:

  1. After Servlet receives the request, data request may need to be carried in some preprocessing;
  2. Some business interface method calls to complete the business process;
  3. Finally, according to the results submitted in response to treatment, the end of the Servlet thread.

A servlet is a single case of multi-threading , and when the servlet thread pool is full time, follow-up visits to the Servletrequest can only wait

The second step of the business process which is usually the most time-consuming, which is mainly reflected in the database operations, as well as other cross-network calls, etc., in the process, Servlet thread has been in a blocked state until the business method is finished. In the process of handling business in, Servlet resource has been occupied and is not released, for larger applications concurrently, which may cause performance bottlenecks. In this regard, in the past usually by private solution to end the Servlet thread in advance and timely release of resources.

Servlet3.0 asynchronous processing

Servlet 3.0 To address this issue done pioneering work, now through the use of asynchronous processing support Servlet 3.0, Servlet process before the process can be adjusted to the following process:

  1. First, after Servlet receives the request, data request may first need to be carried in some preprocessing;
  2. Next, the request to the Servlet thread a thread to perform asynchronous processing operations, the thread itself returned to the vessel, then the response data has not been generated Servlet, after completion of processing asynchronous thread operations, response data may be generated directly ( asynchronous thread owns and ServletRequest ServletResponse referenced object ), or continue to forward the request to other Servlet. Thus, Servlet thread no longer have to wait in a blocked state business logic processing, but can be returned immediately after the start asynchronous thread.

A Code Example:

First create a dynamic web project

public class DemoThread implements Runnable {
    private PrintWriter out;

    public DemoThread(PrintWriter out) {
        this.out = out;
    }

    @Override
    public void run() {
        out.println("子线程---运行<br>");
        int sum = 0;
        for (int i = 0; i < 10; i++) {
            System.out.println("i = " + i);
            sum += i;
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        out.println("sum = " + sum + "<br>");
        out.println("子线程---结束<br>");
    }
}
@WebServlet("/demo")
public class DemoServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.print("主线程开始运行<br>");
        new Thread(new DemoThread(out)).start();
        out.print("主线程运行结束<br>");
    }
}

Annotations created using Servelt3.0 a way DemoServlet, we run tomcat container and access the Servlet

Watch the console:

This is a far cry from what we need to show effect: the main thread directly over, the child is still in the running thread


note:

Servlet asynchronous processing features may be applied to the filter and two kinds of assembly, since the asynchronous operation mode and the normal mode process essentially different in implementation, so by default, and the filter and Servlet asynchronous processing features are not enabled, if desired using this feature, you must be enabled in the following way:

We turned Servelt asynchronous processing, rewrite the code observations:

// asyncSupported 默认为false,
@WebServlet(value = "/demo",asyncSupported = true)
public class DemoServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("进入Servlet的时间:" + new Date() + "<br>");

        //在子线程中执行业务调用,并由其负责输出响应,主线程退出
        AsyncContext ctx = request.startAsync();
        new Thread(new DemoThread(ctx)).start();
        out.println("结束Servlet的时间:" + new Date() + "<br>");
    }
}
public class DemoThread implements Runnable {

    private AsyncContext ctx = null;

    public DemoThread(AsyncContext ctx) {
        this.ctx = ctx;
    }

    @Override
    public void run() {
        int sum = 0;
        try {
            // 通过此种方式就能获取到响应流
            PrintWriter out = ctx.getResponse().getWriter();
            out.println("子线程---运行<br>");
            sum = 0;
            for (int i = 0; i < 10; i++) {
                System.out.println("i = " + i);
                sum += i;
                Thread.sleep(1000L);
            }
            out.println("sum = " + sum + "<br>");
            out.println("子线程---结束<br>");
            out.println("业务处理完毕的时间:" + new Date() + "<br>");
            ctx.complete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Observation time can be found, Servlet thread runs out is over, return to the thread pool, saving resources, if there are multiple requests, will be able to handle the next request. And our DemoThreadthread still able to generate the response data

Guess you like

Origin www.cnblogs.com/heliusKing/p/11620958.html