2

我正在阅读Oracle Docs 中的中断。我无法弄清楚以下部分。它指出

如果一个线程很长时间没有调用抛出 InterruptedException 的方法怎么办?然后它必须定期调用 Thread.interrupted,如果收到中断则返回 true。例如:

for (int i = 0; i < inputs.length; i++) {
    heavyCrunch(inputs[i]);
    if (Thread.interrupted()) {
        // We've been interrupted: no more crunching.
        return;
    }
}

我正在挠头去理解,如果一个线程很长时间没有调用抛出 InterruptedException 的方法,这意味着什么?其次,Thread.interrupted()有什么用,它是一种方式,线程可以给自己发送中断?这个场景的实际用途是什么?谢谢。

4

6 回答 6

4

这是一种保持线程可用于中断的技术。

Thread.interrupted() :检查当前线程(本身)是否被其他线程中断并清除中断状态标志。所以它会问自己,当我正在执行一项 BIG BIG 任务而不听别人讲话时,我是否被某人打断退出我正在做的事情。

想象一下如果那件事没有完成会发生什么。

假设一次迭代heavyCrunch()需要 1 分钟的时间。所以 n 次迭代将需要 n 分钟。

现在假设在启动程序后,您决定要退出程序并优雅地终止程序。因此,您中断了执行繁重工作的线程。但是线程不知道您已经中断了它,因为它没有检查中断状态。所以程序直到N 分钟还没有完成才会结束,你将不得不等待很长时间

因此,要优雅地终止线程,它应该始终检查中断状态以在其他人请求中断时做出响应。

于 2013-08-07T09:56:23.133 回答
3

除了这个短语

如果一个线程很长时间没有调用抛出 InterruptedException 的方法怎么办?

非常不清楚,我想它们的意思如下:

通常,如果您有一个在 while(true) 循环中执行某些工作的线程,即一个长时间不终止的线程,您可能会在该线程中放置任何抛出 InterruptedException 的函数(即 Thread.sleep ()、套接字读取或任何东西!)。这样,当您的线程被注意到一个中断时,其中一个函数将捕获它,您将能够退出您在线程中所做的事情(线程不只是神奇地自行终止)。

这句话想说的是:

如果您不想/必须使用这些功能怎么办?然后你应该使用 Thread.interrupted() 来检查你是否应该退出线程正在做的事情,就像你捕获一个 InterruptedException 时所做的那样。

我希望这比文档更清楚...

于 2013-08-07T10:07:12.657 回答
2

如果您中断运行此代码的线程

for (int i = 0; i < inputs.length; i++) {
    heavyCrunch(inputs[i]);
}

它只会在线程中设置中断状态,但不会停止它

Thread.interrupted测试是否设置了中断状态(并清除它)所以通过添加

if (Thread.interrupted()) {
   return;
}

到你使代码可中断的循环

于 2013-08-07T10:00:05.020 回答
0

我正在挠头去理解,如果一个线程很长时间没有调用 throws 的方法,这意味着什么InterruptedException

A:如果其他线程调用了interupt()该线程的方法,并且该线程在调用该类的、、、或方法,或者该类的、、、、或,方法的调用wait()wait(long)wait(long, int)阻塞Object,则其中断join()状态为被清除,它将收到一个. 否则,只需设置中断状态。join(long)join(long, int)sleep(long)sleep(long, int)InterruptedException

其次, 的用途是什么Thread.interrupted(),它是一种方式,线程可以向自己发送中断?这个场景的实际用途是什么?

A:Thread.interrupted()用于检测当前线程的中断状态,true如果设置则返回,然后清除状态。你检查这个是为了响应其他线程的中断调用,比如抛出一个InterruptedException并退出线程或者只是退出。

于 2013-08-07T10:02:26.180 回答
0

您可以在某处通过 intrrup 线程很好地使用 interrupted() 停止任何长时间运行的线程,并通过Thread.interrupted()并基于此退出运行方法检查条件。

假设您的一个线程在某个监视器上被阻塞,而该线程在其他地方被中断,这反过来会抛出InterruptedException并且可以以中断状态退出阻塞状态true

我认为中断是实现停止的最佳方式,long running task因为中断会解除阻塞一些阻塞的 IO 和synchronization请求。定制解决方案无法做到这一点。

可以帮助你。

于 2013-08-07T09:56:26.243 回答
0

interrupt()从对象中的标志外部设置,然后可以Interrupted()run()方法中定期查询。

于 2013-08-07T09:57:42.940 回答