0

「サーブレット 3.0 での非同期処理のサポート」( http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html?page=2 )に関するエキスパート (?) チュートリアルを行っていました。 . その中には、次のコード スニペットがあります。

@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) {
    }

}

これは専門家の「これがどのように行われるか」の記事だったので、彼らがばかげたコードを書いているわけではないと思います。しかし、「contextInitialized()」内に「while(true)」ループがあることを受け入れることができません。

  1. 私の理解によると、このコンテキストリスナースレッドは「contextInitialized()」メソッドを終了しません。右 ?
  2. アプリケーションにある他のサーブレットはどうなりますか? 彼らは無料でリクエストを処理できますか? それとも、サーブレット コンテナ全体が停止するのでしょうか。
4

1 に答える 1

2

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();
    }
}

2) urlPattern が異なる限り、他のサーブレットは影響を受けません。

于 2013-03-27T19:23:49.623 に答える