【问题标题】:What does Thread.interrupt() do if the thread isn't blocked?如果线程没有被阻塞,Thread.interrupt() 会做什么?
【发布时间】:2014-05-23 20:25:43
【问题描述】:

Thread 的 JavaDoc 说 Thread.interrupt() 中断线程如下:

  • 在 Object 的 wait() 方法之一或 Thread 的方法之一中阻塞的线程 join()sleep() 方法将被唤醒,它们的中断状态 将被清除,他们会收到InterruptedException
  • InterruptibleChannel 的 I/O 操作中阻塞的线程将设置其中断状态并接收ClosedByInterruptException。此外,该频道将被关闭。
  • Selector 中阻塞的线程将设置其中断状态并立即返回。在这种情况下,他们不会收到异常。

如果主题不符合上述任何条件怎么办?它是被杀死还是继续运行还是什么?

提前谢谢...

【问题讨论】:

  • 阅读 javadoc 的其余部分。 If none of the previous conditions hold then this thread's interrupt status will be set.
  • 它会继续,创建代码的人应该检查它是否被使用 Thread.isInterrupted() 中断
  • @MarcoAcierno:请将此作为答案发布,以便我批准。
  • @SotiriosDelimanolis 我引用了 Android 文档,但没有提及。我不会再犯这个错误了。
  • 好吧,也许我有点苛刻,因为你说得很好。 Android javadoc 不一定说与 Java javadoc 相同的东西,因为有些东西不受支持。我很确定在这种情况下它会做同样的事情。

标签: java android multithreading concurrency


【解决方案1】:

如果被中断的线程没有检查Thread.isInterrupted() 并对其进行处理,那么在未阻塞线程上调用Thread.interrupt() 只会简单地设置标志。使用Thread.isInterrupted() 正确检查线程的状态并采取适当的措施是线程实现者的工作。

【讨论】:

    【解决方案2】:

    从 JLS 中阅读的一些内容

    17.2.3。中断

    在调用 Thread.interrupt 时发生中断操作,如 以及定义为依次调用它的方法,例如 ThreadGroup.interrupt。

    令 t 为调用 u.interrupt 的线程,对于某个线程 u,其中 t 和你可能是一样的。这个动作会导致你的中断状态 设置为真。

    另外,如果存在某个等待集合包含 u 的对象 m, 然后将 u 从 m 的等待集中删除。这使您能够恢复 等待动作,在这种情况下,这个等待将在重新锁定 m 之后 监控,抛出 InterruptedException。

    Thread.isInterrupted 的调用可以确定线程的 中断状态。静态方法 Thread.interrupted 可能是 由线程调用以观察和清除自己的中断状态。

    来自Thread.interrupt()Javadoc

    公共无效中断()

    中断这个线程。除非当前 线程正在中断自己,这总是被允许的, 调用了该线程的 checkAccess 方法,这可能会导致 要抛出的 SecurityException。

    如果该线程在调用 wait()、wait(long) 时被阻塞, 或 Object 类或 join() 的 wait(long, int) 方法, join(long)、join(long, int)、sleep(long) 或 sleep(long, int)、方法 这个类,那么它的中断状态将被清除,它会 收到一个 InterruptedException。

    如果此线程在可中断的 I/O 操作中被阻塞 通道然后通道将被关闭,线程的中断状态 将被设置,并且线程将收到 ClosedByInterruptException。

    如果该线程在 Selector 中被阻塞,则该线程的中断 状态将被设置,它将立即从选择中返回 操作,可能具有非零值,就像选择器的 唤醒方法被调用。

    如果前面的条件都不成立,那么这个线程的中断 状态将被设置。

    中断一个不活跃的线程不需要有任何效果。

    总结:

    如果一个线程在waitsleepjoin 或其他使其处于等待状态的线程中,它只会抛出InterruptedException 来通知某个线程希望他应该停止他的身份做与死。

    如果它不处于以前的状态之一,它只会设置一个标志(称为中断状态)。正如您所理解的,它什么都不做来避免由早期中断线程引起的一些错误,这可能导致您的对象处于不一致的状态(您不知道它在做什么)。

    这个标志被线程用来知道是否有人要求他停止他的工作,由程序员来选择是否停止线程(你可以随意忽略它。)

    重要提示waitsleep 等方法(如上所述)在抛出异常时会清除标志。如果您执行while(!Thread.isInterrupted()) 之类的操作来记住这一点,这一点很重要。

    如果需要,可以使用isInterruptedinterrupted了解当前标志状态

    两者之间的唯一区别是interrupted重置标志,而isInterrupted 不会。

    另一篇精彩的读物,here

    (ps我希望链接正确的JLS部分,我会搜索更多。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      • 2021-08-29
      相关资源
      最近更新 更多