AsyncContext 无限线程终止

AsyncContext infinite thread termination

我有点困惑 servlet 容器如何在应用程序取消部署阶段或只是超时终止 AsyncContext。例如,应用程序开发人员具有以下代码片段:

@WebServlet(name = "MyServlet", urlPatterns = "/myServlet", asyncSupported = true)
public class MyServlet extends HttpServlet {
    private static Logger log = Logger.getLogger(MyServlet.class);

    @Override  
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        AsyncContext asyncContext = request.startAsync();
        asyncContext.start(new Runnable() {  
            @Override  
            public void run() {  
                log.debug("Start of Task");  

                try {
                    while(true) {
                        response.getWriter().println("random text");
                        Thread.sleep(100);
                    }
                }catch(Exception e) {
                    log.warn("Async processing exception: " + e.getMessage);
                }
                asyncContext.complete();  

                log.debug("End of Task");  
            }  
        });
    }  
}

这是 AsyncContext 启动的可运行的,它永远不会结束,或者直到在 while 循环中抛出一些异常。所以问题是容器将如何终止运行 这种无限可运行 的线程。唯一想到的是 thread.stop(); 但它已被弃用。我几乎可以肯定容器不会调用 thread.interrupt(); 因为它不能保证引用 javadoc 的线程中断并且这里开发人员设置条件 while-true 而不是 while-not-interrupted 因此不对这种情况负责。

感谢任何建议。

如果应用程序开发人员故意使其无限循环,则 Web 容器无法强制关闭线程。

幸运的是,应用程序员可以使用多种机制来确保 AsyncContext 不会无限地 运行。我脑海中的一些想法是:

  • 通过AsyncContext.setTimeout(long)
  • 为请求设置超时
  • 覆盖 Servlet destory() 方法并调用 AsyncContext.complte(),这将在每个侦听器上调用 AsyncListener.onComplete(AsyncEvent)。在使用 AsyncContext.addListener(AsyncListener).
  • 添加侦听器后,您可以附加一个停止进程的侦听器
  • 在 servlet 中手动存储对线程的引用 class 并在 Servlet destory() 方法中停止它。

主要思想是,如果您要编写一个无限循环的线程(并且您关心在关闭时停止线程),您将需要编写一些代码以确保您的线程正确停止。

机会 AsyncContext.start(Runnable) 使用的线程来自托管线程池:

AsyncContext.start(Runnable): Causes the container to dispatch a thread, possibly from a managed thread pool, to run the specified Runnable.

但是,由于规范对此不明确,您需要手动调查 Java EE 实现如何解释此位,以查看它是否使用托管线程。如果是这样,您的线程可能会在应用服务器停止时自动为您停止。