Java 异步上下文无限线程终止
我有点困惑servlet容器如何在应用程序取消部署阶段终止AsyncContext,或者只是超时。例如,application developer有以下代码段:Java 异步上下文无限线程终止,java,multithreading,jakarta-ee,asynchronous,servlet-3.0,Java,Multithreading,Jakarta Ee,Asynchronous,Servlet 3.0,我有点困惑servlet容器如何在应用程序取消部署阶段终止AsyncContext,或者只是超时。例如,application developer有以下代码段: @WebServlet(name = "MyServlet", urlPatterns = "/myServlet", asyncSupported = true) public class MyServlet extends HttpServlet { private static Logger log = Logger.ge
@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启动runnable,它永远不会结束,或者直到在while循环中抛出某个异常。所以问题是容器将如何终止运行这种无限可运行的线程。唯一想到的是thread.stop()代码>但它已被弃用。我几乎可以肯定容器不会调用thread.interrupt()代码>因为它不能保证引用javadoc的线程中断,开发者在这里设置的条件为true而不是未中断,因此不对这种情况负责
感谢您的建议。如果应用程序开发人员有意使线程无限循环,那么web容器无法强制关闭线程
幸运的是,应用程序程序员可以使用几种机制来确保AsyncContext
不会无限运行。我脑子里的一些想法是:
- 通过
AsyncContext.setTimeout(长)
- 重写Servlet
destory()
方法并调用AsyncContext.complte()
,这将在每个侦听器上调用AsyncListener.onComplete(AsyncEvent)
。然后,在使用AsyncContext.addListener(AsyncListener)
添加侦听器之后,可以附加一个停止进程的侦听器
- 在servlet类中手动存储对线程的引用,并在servlet
destory()方法中停止它
其主要思想是,如果您要编写一个无限循环的线程(并且您关心关闭时停止线程),则需要编写一些代码以确保线程正确停止
AsyncContext.start(Runnable)
使用的线程可能来自托管线程池:
AsyncContext.start(Runnable)
:使容器分派线程(可能来自托管线程池)以运行指定的Runnable
然而,由于规范在这方面并不明确,您需要手动研究JavaEE实现如何解释此位,以查看它是否使用托管线程。如果是这样,当应用程序服务器停止时,您的线程可能会自动停止。为什么容器应该终止这样一个可运行的(如果它故意使用无限while循环)?@SabirKhan如果管理员决定使用CLI lib/web UI或其他方法从sevlet容器取消部署应用程序,该怎么办。保持线程运行?您可以重写方法并按您想要的方式完成对象。您好,谢谢您的建议。我想你回答了我的主要问题。如果我错了,请纠正我-应用程序开发人员完全负责线程终止,从而负责防止内存泄漏(使用上述三个选项中的任何一个)。是的,如果您拥有不由容器管理的资源(即由AsyncContext.start(Runnable)
创建的非托管线程)然后您需要手动清理。