gpt4 book ai didi

java - AsyncContext 无限线程终止

转载 作者:行者123 更新时间:2023-11-30 10:51:47 25 4
gpt4 key购买 nike

我有点困惑 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 类中手动存储对线程的引用,并在 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 实现如何解释该位以查看它是否使用托管线程。如果是这样,您的线程可能会在应用服务器停止时自动为您停止。

关于java - AsyncContext 无限线程终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34593273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com