【问题标题】:Understanding the usage of Thread.interrupt()了解 Thread.interrupt() 的用法
【发布时间】:2013-08-08 15:17:51
【问题描述】:

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

如果一个线程很长时间没有调用一个方法怎么办? 抛出中断异常?然后它必须定期调用 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(),是一种方式,那个线程可以给自己发送中断吗?是什么 这个场景的实际用法?谢谢。

【问题讨论】:

标签: java multithreading interrupt


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 感谢您的详细解释。我有一个后续问题,我正在阅读文档,它说如果 Thread.interrupted() 被调用,它会清除状态。那么是不是意味着,即使没有被中断,也会将中断状态设置为true?
  • 否,如果它没有被中断,它不会设置标志。只有当标志为真时,调用该函数才会导致标志为假。而不是相反的。
  • 哦,太好了。那么如果只是为了检查线程是否被中断,调用isInterrupted()而不是interrupted()不是更好吗?
  • Thread.interrupted() 仅用于简写此 Thread.currentThread().isInterrupted()。在内部甚至 Thread.interrupted() 使用 currentThread().isInterrupted()
  • 非常感谢您让我明白这一点。非常感谢。
【解决方案2】:

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

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

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

May help you.

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      如果你中断了运行这段代码的线程

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

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

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

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

      到你使代码可中断的循环

      【讨论】:

        【解决方案5】:

        我摸不着头脑去理解,这是什么意思如果一个线程长时间没有调用抛出InterruptedException的方法怎么办?

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

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

        A:Thread.interrupted()用于检测当前线程的中断状态,如果设置了则返回true,然后清除状态。您检查此项是为了响应其他线程的中断调用,例如抛出InterruptedException 并退出线程或直接退出。

        【讨论】:

          【解决方案6】:

          除了这个短语

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

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

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

          这句话想说的来了:

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

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

          【讨论】:

          • 感谢 Lake,它肯定更加清晰。非常感谢。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多