Java:这是否正确暂停线程?

标签 java multithreading synchronized interrupted-exception spurious-wakeup

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

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

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

最佳答案

摘要

因此,虽然从技术上来说这可行,但有很多原因不应该这样做。 Oracle 的文档指出,中断只能用于取消。但如果您这样做,它将清除中断状态,并且先前等待的线程将收到 InterruptedException

<小时/>

替代方案

让我们逐步完成一个简短、简化的示例。

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

  2. 线程将开始通过wait()等待,并释放监视器。始终在条件中使用 wait(),因为线程可能会从 wait() 中获得虚假唤醒。至此,你已经实现了强制线程等待。

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

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

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

关于Java:这是否正确暂停线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51934163/

相关文章:

java - 类 : interface org. testng.annotations 的重复注释。之前方法

multithreading - 长时间运行的后台线程导致 HTTP 请求超时

python - 创建单例队列 Python

c - 如何使用线程更改函数中的结构变量?

java - 跨类同步

java - 在 Java 中,如何知道 "synchronized"代码花费了多少时间?

java - 在方法中传递 int 数组作为参数 [Java]

java - 将 Map 的 Map 更改为泛型类型

java - 玩框架javascript路由+非静态方法

java - 这段代码是不是违反了临界区的互斥?