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