【问题标题】:Java: Does this pause the thread correctly?Java:这是否正确地暂停了线程?
【发布时间】:2018-08-20 15:37:29
【问题描述】:

我很好奇是否可以通过让t 运行以下暂停代码来暂停 Java 中的线程 t 并允许另一个线程稍后恢复它:

while(true) {
  try {
    synchronized(t) { 
      t.wait();
    }
  } catch(InterruptedException e) {
    break;
  }
}

然后通过调用.interrupt() 来恢复线程t。但是,我读过关于虚假唤醒的文章,所以我想知道我的代码是否会失败,即退出 while 循环,尽管没有其他线程调用 .interrupt()。虽然this answerthis answer 声明没有虚假中断,因此我的代码永远不会失败,the Java docs 似乎没有解决这个问题。我的问题可能归结为InterruptedException 是否在没有被.interrupt() 中断的线程的情况下被抛出。是否有任何官方资料或文件可以证实这一点?

【问题讨论】:

  • 不管是否存在虚假中断,我认为interrupt() 在这种情况下不是一个好主意,应该使用易失性布尔字段来代替。
  • 至少可以说,中断线程并不是恢复线程的最佳方式。
  • 为什么要在线程对象上使用synchronized?您同步多个线程使用的对象,而不是线程本身。使用waitnotify 暂停和恢复。
  • 此外,除非这是出于学习目的,否则您可能只从 java.util.concurrent 中选择一个完全满足您需要的课程,在您的情况下可能是 CountdownLatchCyclicBarrier
  • @biziclop:我想确切地知道它是如何工作或不工作的,所以你可以说这是为了我的学习目的。

标签: java multithreading synchronized interrupted-exception spurious-wakeup


【解决方案1】:

总结

因此,尽管从技术上讲这可行,但有很多原因不应该这样做。 Oracle 的文档指出,中断只能用于取消。但是如果你这样做,它会清除中断状态,之前等待的线程会收到一个InterruptedException


替代方案

让我们逐步介绍一个简短的简化示例。

Object obj = new Object;
synchronized (obj) {
    while(condition) {
        obj.wait();
    }
} 
  1. 这里的thread 将获得监视器。

  2. thread 将通过wait() 开始等待,然后释放监视器。始终在条件中使用wait(),因为线程会受到来自wait() 的虚假唤醒。至此,你已经实现了强制线程等待。

让我们研究一下如何让线程恢复工作。

synchronized(obj) {
    obj.notify();
}

notify() 将唤醒监视器上第一个等待的thread。现在,如果您希望唤醒所有等待的线程,请改用notifyAll()。这是wait()/notify() 的预期目的和功能,因此应该在wait()/interrupt() 上使用。有关其他示例,请参阅this article

【讨论】:

  • 感谢您的回答,但我真正的问题仍然存在:“是否有任何官方资料或文档可以证实这一点?”。至于wait()notify() 的“预期用途和功能”,我知道。但是,正如您所说,notify() 唤醒第一个等待obj 的线程,这就是为什么我改用t.wait(),以便每个暂停的线程t 等待一个唯一的监视器和任何其他线程引用t 的可以恢复t。另外,我对没有虚假中断的 2 个答案很感兴趣。
  • 是的,这就是为什么我说我的真正问题仍未得到解答。请记住,我要求官方文档确认当线程被中断时必须始终由于.interrupt()。你的答案现在是我在 SO 上知道的第三个这样说的答案,但是 Nathan Hughes 在对我的问题的评论中似乎对此表示怀疑。这就是为什么我想要官方文档,或者至少是来自实际看过 Java 实现的人的信息。谢谢!
  • "一个线程通过在Thread对象上调用interrupt来发送一个中断,以便线程被中断。" docs.oracle.com/javase/tutorial/essential/concurrency/…
  • 所以你是说没有提到虚假中断意味着这是不可能的?我在这里看到了很多这种推理,但对我来说并不是很有说服力。
  • 不,您只是要求一些东西来明确支持您的主张,而我在您要求的文档中为您提供证据。
猜你喜欢
  • 2019-08-09
  • 1970-01-01
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多