Java:这样可以正确暂停线程吗?

时间:2018-08-20 15:37:30

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

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

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

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

1 个答案:

答案 0 :(得分: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