Servlets 异步Servlet-首选实现

Servlets 异步Servlet-首选实现,servlets,asynchronous,java-ee-6,servlet-3.0,java-ee-7,Servlets,Asynchronous,Java Ee 6,Servlet 3.0,Java Ee 7,最近,在我研究servlet中的异步处理时,我至少遇到了三种实现方法 有些功能使用这种方法 问题是: 哪一个是最好的 也许这些方法中有一些是不推荐的 也许还有一种方法比下面提到的更好 找到的方法: 使用AsyncContext.start(Runnable) 这种方法非常简单和直接。但许多服务器在为HTTP请求创建的线程池中执行这样的作业 (更多信息请参见此处) 使用Servlet上下文初始化期间创建的自定义线程池 (此处示例:)。 但我可以在Servlet容器中创建自己的线程吗?在EJB(在

最近,在我研究
servlet
中的异步处理时,我至少遇到了三种实现方法 有些功能使用这种方法

问题是:

  • 哪一个是最好的
  • 也许这些方法中有一些是不推荐的
  • 也许还有一种方法比下面提到的更好
  • 找到的方法:

  • 使用
    AsyncContext.start(Runnable)

    这种方法非常简单和直接。但许多服务器在为
    HTTP
    请求创建的线程池中执行这样的作业 (更多信息请参见此处)

  • 使用Servlet上下文初始化期间创建的自定义线程池

    (此处示例:)。 但我可以在Servlet容器中创建自己的线程吗?在
    EJB
    (在
    JavaEE7
    之前)中不建议(甚至禁止)使用它。 我可以使用
    JavaSE
    执行器还是应该使用
    JavaEE7
    中的
    ManagedExecutors
    (假设我使用
    JavaEE7

  • 使用
    EJB
    @asynchronous
    注释

    (此处示例:)。 但在这里,我无法控制执行任务的线程(即应该创建多少线程等)


  • 我很高兴听到您对这个问题的看法,以及您使用
    AsyncContext

    的经验,所有线程都将具有相同的性能,在后端,所有线程都将请求处理线程替换为另一个线程,以便可以处理更多的请求

    下面是一个简单的实现:

    @WebServlet(urlPatterns = "/AsyncLongRunningServlet", asyncSupported = true)
    public class AsyncLongRunningServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
            System.out.println("Request Processing Thread "+Thread.currentThread().getName());
    
            request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
            response.setContentType("text/html");
            PrintWriter printWriter=response.getWriter();
            printWriter.println("<html><head><title>Asynchronous servlet</title></head><body>");
            printWriter.println("Request Processing Thread "+Thread.currentThread().getName());
            printWriter.println("<br>");
            printWriter.println("<progress id='progress' max='100')></progress>");
            printWriter.println("<br>");
    
            AsyncContext asyncCtx = request.startAsync();
            asyncCtx.addListener(new AppAsyncListener());
            asyncCtx.setTimeout(12000);
            //release of request processing thread
            asyncCtx.start(() ->{
                printWriter.println("<br>");
                printWriter.println("Async thread Name "+Thread.currentThread().getName());
                printWriter.println("<br>");
    
                int i=0;
                while(i<100)
                {
                    printWriter.println("<script>document.getElementById('progress').value=\""+i+"\";</script>");
                    printWriter.flush();
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {
                    }
                    i++;
                }
                printWriter.println("</body></html>");
                asyncCtx.complete();
            }
    
        );
            printWriter.println("<br>");
            printWriter.println("End of response");
        }
    
    }
    
    
    
    package com.journaldev.servlet.async;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.AsyncEvent;
    import javax.servlet.AsyncListener;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebListener;
    
    @WebListener
    public class AppAsyncListener implements AsyncListener {
    
        @Override
        public void onComplete(AsyncEvent asyncEvent) throws IOException {
            System.out.println("AppAsyncListener onComplete");
            // we can do resource cleanup activity here
        }
    
        @Override
        public void onError(AsyncEvent asyncEvent) throws IOException {
            System.out.println("AppAsyncListener onError");
            //we can return error response to client
        }
    
        @Override
        public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
            System.out.println("AppAsyncListener onStartAsync");
            //we can log the event here
        }
    
        @Override
        public void onTimeout(AsyncEvent asyncEvent) throws IOException {
            System.out.println("AppAsyncListener onTimeout");
            //we can send appropriate response to client
            ServletResponse response = asyncEvent.getAsyncContext().getResponse();
            PrintWriter out = response.getWriter();
            out.write("TimeOut Error in Processing");
        }
    
    }
    
    @WebServlet(urlPatterns=“/AsyncLongRunningServlet”,asyncSupported=true)
    公共类AsyncLongRunningServlet扩展了HttpServlet{
    私有静态最终长serialVersionUID=1L;
    受保护的无效数据集(HttpServletRequest请求,
    HttpServletResponse响应)引发ServletException,IOException{
    System.out.println(“请求处理线程”+线程.currentThread().getName());
    setAttribute(“org.apache.catalina.ASYNC_-SUPPORTED”,true);
    response.setContentType(“text/html”);
    PrintWriter PrintWriter=response.getWriter();
    printWriter.println(“异步servlet”);
    printWriter.println(“请求处理线程”+线程.currentThread().getName());
    printWriter.println(“
    ”); printWriter.println(“”); printWriter.println(“
    ”); AsyncContext asyncCtx=request.startAsync(); addListener(新的AppAsyncListener()); asyncCtx.setTimeout(12000); //释放请求处理线程 asyncCtx.start(()->{ printWriter.println(“
    ”); printWriter.println(“异步线程名称”+线程.currentThread().getName()); printWriter.println(“
    ”); int i=0; 而