在我的应用程序中,每个请求都有自己的线程。我使用JMX / JConsole监视它们,测量经过的时间。如果一个请求需要太多时间,我想通过中断底层线程来阻止它。 在我从JConsole调用的方法中,我遍历线程列表并在右侧实例上调用interrupt() 但是,只是在线程实例上调用interrupt()方法只会设置一个标志,所以我也需要抛出一个InterruptedException。 但是这个InterruptedException将应用于currentThread而不是我实际想要停止的线程。有没有提示如何关闭被标记的线程?
while (iterator.hasNext()) {
RequestHolder rh = iterator.next();
if (rh.getThread().getId() == threadId) {
rh.getThread().interrupt();
if(rh.getThread().isInterrupted()){
throw new InterruptedException();
}
}
}
答案 0 :(得分:2)
但是这个InterruptedException将应用于currentThread而不是我实际想要停止的线程。
您可以使用isInterrupted
检查任何线程的中断状态。但是,如果您不知道如何以及何时消耗中断,则不建议将其作为黑盒方法。
任何提示如何关闭被标记的线程?
您无法从另一个线程中干净地关闭线程。
但这很简单。在正在运行的线程中,定期检查Interruption
,例如在循环捕获InterruptedException
中检查阻塞函数。当您看到线程中断时,请使其自行终止。从某种意义上说,线程实现了自己的终止策略。
答案 1 :(得分:1)
抛出InterruptedException没有任何好处。您的if (rh.getThread().isInterrupted())
块可以删除。
每个线程必须监视自己的中断状态,并且在看到它被中断时必须正常退出。
通常代码看起来像这样:
try {
InputStream in = socket.getInputStream();
while (in.read(buffer) >= 0) {
if (Thread.interrupted()) {
logger.log(Level.FINE, "Interrupted; exiting");
break;
}
// Process request buffer here
}
} catch (InterruptedIOException e) {
logger.log(Level.FINE, "Interrupted; exiting", e);
}
如果你正在使用频道,你也想要捕捉ClosedByInterruptException。
答案 2 :(得分:0)
您可以在负责执行第一个终止的线程的构造函数中传递要终止的线程的引用。然后你可以使用来自另一个线程的引用来销毁线程。