1) 假设在请求线程中我们执行了一些任务,例如调用其他Web服务、数据库等。当客户端关闭HTTP连接时,请求线程是否会被终止/停止运行中的任何任务?如果不是,那么如何终止?
2) 如果在请求线程中执行一些并行任务,生成一些新线程(使用ExecutorService和固定池大小),在HTTP连接关闭的情况下,如何终止/停止请求线程内生成的这些子线程?
1) 假设在请求线程中我们执行了一些任务,例如调用其他Web服务、数据库等。当客户端关闭HTTP连接时,请求线程是否会被终止/停止运行中的任何任务?如果不是,那么如何终止?
2) 如果在请求线程中执行一些并行任务,生成一些新线程(使用ExecutorService和固定池大小),在HTTP连接关闭的情况下,如何终止/停止请求线程内生成的这些子线程?
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容器不会为您执行此操作。
Tomcat有一个名为minSpareThreads的属性。未使用的线程将被销毁,除非它在minSpareThreads范围内。
minSpareThreads
始终运行的最小线程数。如果未指定,则使用默认值10。
在HTTP连接关闭的情况下,如何终止/杀死请求线程中生成的这些线程?
有多种方法可以实现。首先需要注意的是,在正常的Tomcat使用中,处理请求的Servlet不会收到有关连接关闭的通知。但是,Tomcat具有高级IO功能,可以用于拦截连接关闭,如果Tomcat将其视为错误并向您发送在该链接中提到的CometEvent(需要进一步测试)。
现在假设你已经等待线程完成(超时)或通过某种方式收到连接关闭通知,那么您需要中断您的工作线程(即您正在尝试停止的线程)。这通常分为两个步骤。1)将共享的原子或易失性布尔对象设置为表示“停止处理”的值,一种控制标志。2)然后中断您的线程。工作线程应该跳出任何阻塞方法,然后可以检查共享变量(控制标志)是否设置为“停止”。如果您的工作线程在执行某些代码的一次迭代后自然停止,则可以跳过步骤1。有些线程会一直循环,直到其控制标志设置为“停止”。如果您正在使用ExecutorService,则其shutdownNow方法通常会向其池中运行的所有线程发送Thread.interrupt。