Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ServletContextListener:Isn';这不是不正确的用法吗?_Java_Multithreading_Jakarta Ee_Servlet 3.0 - Fatal编程技术网

Java ServletContextListener:Isn';这不是不正确的用法吗?

Java ServletContextListener:Isn';这不是不正确的用法吗?,java,multithreading,jakarta-ee,servlet-3.0,Java,Multithreading,Jakarta Ee,Servlet 3.0,我正在阅读一篇关于“Servlet3.0中的异步处理支持”(AsynchronousProcessingSupportinServlet3.0)的专家教程。其中包含以下代码段: @WebServlet(name="myServlet", urlPatterns={"/slowprocess"}, asyncSupported=true) public class MyServlet extends HttpServlet { public void doGet(HttpServletR

我正在阅读一篇关于“Servlet3.0中的异步处理支持”(AsynchronousProcessingSupportinServlet3.0)的专家教程。其中包含以下代码段:

@WebServlet(name="myServlet", urlPatterns={"/slowprocess"}, asyncSupported=true)
public class MyServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        AsyncContext aCtx = request.startAsync(request, response);
        ServletContext appScope = request.getServletContext();
        ((Queue<AsyncContext>)appScope.getAttribute("slowWebServiceJobQueue")).add(aCtx);
    }
}

@WebServletContextListener
public class SlowWebService implements ServletContextListener {

    public void contextInitialized(ServletContextEvent sce) {
        Queue<AsyncContext> jobQueue = new ConcurrentLinkedQueue<AsyncContext>();
        sce.getServletContext().setAttribute("slowWebServiceJobQueue", jobQueue);
        // pool size matching Web services capacity
        Executor executor = Executors.newFixedThreadPool(10);
        while(true)
        {
            if(!jobQueue.isEmpty())
            {
                final AsyncContext aCtx = jobQueue.poll();
                executor.execute(new Runnable(){
                    public void run() {
                        ServletRequest request = aCtx.getRequest();
                        // get parameteres
                        // invoke a Web service endpoint
                        // set results
                        aCtx.forward("/result.jsp");
                    }
                });
            }
        }
    }

    public void contextDestroyed(ServletContextEvent sce) {
    }
@WebServlet(name=“myServlet”,urlPatterns={”/slowprocess},asyncSupported=true)
公共类MyServlet扩展了HttpServlet{
public void doGet(HttpServletRequest请求、HttpServletResponse响应){
AsyncContext aCtx=request.startAsync(请求,响应);
ServletContext appScope=request.getServletContext();
((队列)appScope.getAttribute(“slowWebServiceJobQueue”)).add(aCtx);
}
}
@WebServletContextListener
公共类SlowWebService实现ServletContextListener{
public void contextInitialized(ServletContextEvent sce){
队列作业队列=新ConcurrentLinkedQueue();
sce.getServletContext().setAttribute(“slowWebServiceJobQueue”,jobQueue);
//池大小与Web服务容量匹配
Executor Executor=Executors.newFixedThreadPool(10);
while(true)
{
如果(!jobQueue.isEmpty())
{
final AsyncContext aCtx=jobQueue.poll();
executor.execute(新的Runnable(){
公开募捐{
ServletRequest=aCtx.getRequest();
//获取参数
//调用Web服务端点
//设定结果
aCtx.forward(“/result.jsp”);
}
});
}
}
}
公共无效上下文已销毁(ServletContextEvent sce){
}
}

因为这是一篇专家的“这就是如何做到的”文章,我想他们不会写一些愚蠢的代码。 但我无法接受在“contextInitialized()”中有一个“while(true)”循环

  • 根据我的理解,这个上下文侦听器线程永远不会退出“contextInitialized()”方法。对吧?
  • 我的应用程序中的任何其他servlet会发生什么情况?他们可以免费为请求提供服务吗?或者这会导致整个servlet容器崩溃 1) 我将更改代码如下:

    @WebServletContextListener
    public class SlowWebService implements ServletContextListener, Runnable {
        private volatile boolean running;
        ExecutorService executor;
        Thread runner;
        Queue<AsyncContext> jobQueue;
    
        public void contextInitialized(ServletContextEvent sce) {
            jobQueue = new ConcurrentLinkedQueue<AsyncContext>();
            sce.getServletContext().setAttribute("slowWebServiceJobQueue", jobQueue);
            // pool size matching Web services capacity
            executor = Executors.newFixedThreadPool(10);
            runner = new Thread(this);
            runner.start();
        }
    
        public void run() {
            running = true;
            while(running)
            {
                try {
                    if(!jobQueue.isEmpty())
                    {
                        final AsyncContext aCtx = jobQueue.poll();
                        executor.execute(new Runnable(){
                            public void run() {
                                ServletRequest request = aCtx.getRequest();
                                // get parameteres
                                // invoke a Web service endpoint
                                // set results
                                aCtx.forward("/result.jsp");
                            }
                        });
                    }
                }
                catch (InterruptException e) {
                }
            }
        }
    
        public void contextDestroyed(ServletContextEvent sce) {
            running = false;
            runner.interrupt();
            executor.shutdown();
        }
    }
    
    @WebServletContextListener
    公共类SlowWebService实现ServletContextListener,Runnable{
    私有化;布尔运行;
    执行人服务执行人;
    螺纹流道;
    队列作业队列;
    public void contextInitialized(ServletContextEvent sce){
    jobQueue=新的ConcurrentLinkedQueue();
    sce.getServletContext().setAttribute(“slowWebServiceJobQueue”,jobQueue);
    //池大小与Web服务容量匹配
    executor=Executors.newFixedThreadPool(10);
    流道=新螺纹(此);
    runner.start();
    }
    公开募捐{
    运行=真;
    (跑步时)
    {
    试一试{
    如果(!jobQueue.isEmpty())
    {
    final AsyncContext aCtx=jobQueue.poll();
    executor.execute(新的Runnable(){
    公开募捐{
    ServletRequest=aCtx.getRequest();
    //获取参数
    //调用Web服务端点
    //设定结果
    aCtx.forward(“/result.jsp”);
    }
    });
    }
    }
    捕获(中断异常){
    }
    }
    }
    公共无效上下文已销毁(ServletContextEvent sce){
    运行=错误;
    runner.interrupt();
    executor.shutdown();
    }
    }
    

    2) 只要其他servlet具有不同的urlPattern,它们就不会受到影响。

    此代码不会在contextDestroyed上清除,也不会停止运行。“执行器”由“runner”线程和“context listener事件处理”线程访问。它是否应该是易变的或以某种方式同步的?我想将“running”设置为false并“interrupt”线程的原因是为了强制线程退出其“poll”,并让它查看是否应该继续“running”。是吗?@vendhan是的,是的,否则当上下文被破坏时线程不会停止。在这种情况下,您不需要同步执行器。同意在引用后不需要同步执行器,但令人难以置信的是,规范中没有正确记录这一点!你能回答问题2吗?所以我可以选择这个作为答案。