Tomcat:当HTTP连接关闭时终止在请求线程中生成的线程

6
在Tomcat 6/7中:

1) 假设在请求线程中我们执行了一些任务,例如调用其他Web服务、数据库等。当客户端关闭HTTP连接时,请求线程是否会被终止/停止运行中的任何任务?如果不是,那么如何终止?

2) 如果在请求线程中执行一些并行任务,生成一些新线程(使用ExecutorService和固定池大小),在HTTP连接关闭的情况下,如何终止/停止请求线程内生成的这些子线程?


2
使用队列而不是在Servlet容器中启动线程。这在J2EE标准中被明确禁止。ActiveMQ + Tomcat = TomEE。 - bobs_007
https://dev59.com/wEbRa4cB1Zd3GeqPwxX_ - bobs_007
2个回答

2

a.) 线程会继续运行。当/如果它最终返回某些内容时,它将因为正在尝试写入的连接已经关闭而失败并抛出套接字异常。在普通的servlet API中,您无法告诉线程连接何时已关闭。

b.) 如果您生成额外的线程,一种简单的监视方法是使用Java并发包中的Callables和Futures。这为您处理超时提供了方便的方式。请查看此文档:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html

以及这里:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html

无论如何,您需要负责监视线程并确保它们不会永远运行,您的servlet容器不会为您执行此操作。


1

Tomcat有一个名为minSpareThreads的属性。未使用的线程将被销毁,除非它在minSpareThreads范围内。

minSpareThreads
始终运行的最小线程数。如果未指定,则使用默认值10。

在HTTP连接关闭的情况下,如何终止/杀死请求线程中生成的这些线程?

有多种方法可以实现。首先需要注意的是,在正常的Tomcat使用中,处理请求的Servlet不会收到有关连接关闭的通知。但是,Tomcat具有高级IO功能,可以用于拦截连接关闭,如果Tomcat将其视为错误并向您发送在该链接中提到的CometEvent(需要进一步测试)。

现在假设你已经等待线程完成(超时)或通过某种方式收到连接关闭通知,那么您需要中断您的工作线程(即您正在尝试停止的线程)。这通常分为两个步骤。1)将共享的原子或易失性布尔对象设置为表示“停止处理”的值,一种控制标志。2)然后中断您的线程。工作线程应该跳出任何阻塞方法,然后可以检查共享变量(控制标志)是否设置为“停止”。如果您的工作线程在执行某些代码的一次迭代后自然停止,则可以跳过步骤1。有些线程会一直循环,直到其控制标志设置为“停止”。如果您正在使用ExecutorService,则其shutdownNow方法通常会向其池中运行的所有线程发送Thread.interrupt。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接