1

在我的应用程序中,每个请求都有自己的线程。我使用 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();
                        }
                    }
                }
4

3 回答 3

2

但是这个 InterruptedException 将适用于 currentThread 而不是我真正想要停止的线程。

您可以使用 . 检查任何线程的中断状态isInterrupted。但是,如果您不知道如何以及何时消耗中断,则不建议将其作为黑盒方法。

任何提示如何关闭标记的线程?

您不能从另一个线程干净地关闭一个线程。

但这很简单。在正在运行的线程中,定期检查是否有阻塞功能Interruption,例如循环捕获InterruptedException。当您看到线程中的中断时,使其自行终止。从某种意义上说,线程实现了它们自己的终止策略。

于 2013-05-13T13:48:37.313 回答
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);
}

如果您使用的是 Channels,您还需要捕获 ClosedByInterruptException。

于 2013-05-13T13:51:44.037 回答
0

您可以在负责执行第一个终止的线程的构造函数中传递要终止的线程的引用。然后,您可以使用来自另一个线程的引用来销毁该线程。

于 2013-05-13T15:10:59.810 回答