Each request comes to the Web container, and the Web container assigns it a thread that is specifically responsible for the request, and the thread is not freed back to the container until the response is complete. threads consume system resources, and if some requests take a long time to process (such as long-time operations, waiting for a resource), it takes a long time to consume threads, and if such requests are large, many threads are occupied for a longer period of time, which can be a performance burden for the system. It even creates an application's performance bottleneck.
basically some long processing requests, usually the client does not care about the request to have an immediate response, if possible, let such a request to release the container allocated to the request of the thread, so that the container can have the opportunity to allocate thread resources to other requests, can alleviate the system burden. The request that originally freed the container's allocated thread will be deferred until the processing is completed (for example, the long-time operation is complete and the required resources have been obtained) and the response to the client.
in servlet 3.0, the startasync ( ) method is available on ServletRequest :
Java code
- Asynccontext Startasync () throws java.lang.IllegalStateException;
- Asynccontext Startasync (ServletRequest servletrequest,
- Servletresponse servletresponse)
- Throws Java.lang.IllegalStateException
Both of these methods will return the real-crop pieces of the Asynccontext interface, which directly uses the original request and response object to build the Asynccontext, which allows you to pass in the request that you set up and respond to the parcel object. after calling the Startasync () method to get the Asynccontext object, the response is deferred and the thread allocated by the container is freed.
You can asynccontext by getresponse () method Get request, reply object, The response to the client will be deferred to the call Asynccontext complete () method or
to be able to call ServletRequest's Startasync () using Asynccontext, your Servlet must be able to support non-synchronous processing, and if you use @webservlet to label it, you can set its asyncsupported is true. For example:
Java code
- @WebServlet (urlpatterns = "/some.do", asyncsupported = true)
- Public class Asyncservlet extends HttpServlet {
- ...
If you set the servlet using Web. XML, you can set the <async-supported> tag to true :
XML code
- ...
- <servlet>
- <servlet-name>asyncservlet</servlet-name>
- <servlet-class>cc.openhome.asyncservlet</servlet-class>
- <async-supported>true</async-supported>
- </servlet>
- ...
If the servlet will be unsynchronized, and if there is a filter on its front-end, the filter must also indicate that it supports non-synchronous processing, and if @WebFilter is used, it can also be set to asyncsupported true. For example :
Java code
- @WebFilter (urlpatterns = "/some.do", asyncsupported = true)
- Public class Asyncfilter implements filter{
- ...
If you set a filter using Web. XML, you can set the <async-supported> tag to true:
XML code
- ...
- <filter>
- < filter-name>asyncfilter</ filter-name>
- < filter-class>cc.openhome.asyncfilter</ filter-class>
- <async-supported>true</async-supported>
- </ filter >
- ...
Below is an example of a non-synchronous processing that, for incoming requests, the servlet obtains its asynccontext and releases the thread allocated by the container, the response is deferred, and a Runnable object is created for these deferred response requests. , and it is queued to a thread pool, the number of threads in the thread pool is fixed, so that those requests that must be processed for a long time are completed in these limited numbers of threads, without having to consume the thread allocated by the container each time the request is made.
Java code
- Package cc.openhome;
- import java.io.*;
- import java.util.concurrent.*;
- import javax.servlet.*;
- import javax.servlet.annotation.*;
- import javax.servlet.http.*;
- @WebServlet (name="Asyncservlet", urlpatterns={"/async.do"},
- asyncsupported = true)
- public class Asyncservlet extends HttpServlet {
- //thread pool
- private Executorservice Executorservice = Executors.newfixedthreadpool (10);
- protected void ProcessRequest (HttpServletRequest request,
- HttpServletResponse response)
- throws Servletexception, IOException {
- Response.setcontenttype ("text/html; Charset=utf8 ");
- Asynccontext CTX = Request.startasync ();
- Executorservice.submit (new Asyncrequest (CTX));
- }
- @Override
- protected void doget (HttpServletRequest request,
- HttpServletResponse response)
- throws Servletexception, IOException {
- ProcessRequest (request, response);
- }
- @Override
- protected void DoPost (HttpServletRequest request,
- HttpServletResponse response)
- throws Servletexception, IOException {
- ProcessRequest (request, response);
- }
- @Override
- public Void Destroy () {
- Executorservice.shutdown ();
- }
- }
Asyncrequest is a class of practice runnable that simulates a long processing period:
Java code
- Package cc.openhome;
- import Java.io.PrintWriter;
- import Javax.servlet.AsyncContext;
- public class Asyncrequest implements Runnable {
- private Asynccontext CTX;
- Public asyncrequest (Asynccontext ctx) {
- this.ctx = CTX;
- }
- @Override
- public Void Run () {
- try {
- //Analog long-time processing
- Thread.Sleep (10000);
- PrintWriter out = Ctx.getresponse (). Getwriter ();
- Out.println ("Waiting for ... XD ");
- //This side only really sends out the response
- Ctx.complete ();
- } catch (Exception e) {
- E.printstacktrace ();
- }
- }
- }
Servlet3.0: Introduction Asynccontext