Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.util.concurrent.locks.Condition waitunterruptibly()_Java_Multithreading_Concurrency_Wait - Fatal编程技术网

java.util.concurrent.locks.Condition waitunterruptibly()

java.util.concurrent.locks.Condition waitunterruptibly(),java,multithreading,concurrency,wait,Java,Multithreading,Concurrency,Wait,当我阅读java.util.concurrent.locks.ConditionAPI文档时 我看到: 在等待某个条件时,允许执行“虚假唤醒” 通常,作为对基础平台的让步而发生 语义学。这对大多数应用程序几乎没有实际影响 作为条件的程序应始终在循环中等待, 正在测试正在等待的状态谓词。一 实现可以自由消除虚假唤醒的可能性 但建议应用程序程序员始终假定 它们可能发生,因此总是在循环中等待 等待的声音不间断地说: 如果当前线程进入此状态时设置了中断状态 方法,或者它在等待时被中断,它将继续等待 直到

当我阅读
java.util.concurrent.locks.Condition
API文档时

我看到:

在等待某个条件时,允许执行“虚假唤醒” 通常,作为对基础平台的让步而发生 语义学。这对大多数应用程序几乎没有实际影响 作为条件的程序应始终在循环中等待, 正在测试正在等待的状态谓词。一 实现可以自由消除虚假唤醒的可能性 但建议应用程序程序员始终假定 它们可能发生,因此总是在循环中等待

等待的声音不间断地说:

如果当前线程进入此状态时设置了中断状态 方法,或者它在等待时被中断,它将继续等待 直到发出信号。当它最终从此方法返回时 仍将设置中断状态

那么,这是否意味着我们不需要在循环中不间断地调用waitingly()?请澄清。提前感谢。

代码:

public final void awaitUninterruptibly() {
  Node node = addConditionWaiter();
  int savedState = fullyRelease(node);
  boolean interrupted = false;
  while (!isOnSyncQueue(node)) {
    LockSupport.park(this);
    if (Thread.interrupted()) interrupted = true;
  }
  if (acquireQueued(node, savedState) || interrupted) selfInterrupt();
}
因此,等待是在循环中完成的,这将消除在该函数外部循环的需要

但是请记住,这也意味着
Thread.interrupt()
不会执行任何操作,这可能会导致代码的某些锁定,即在关机期间。

代码:

public final void awaitUninterruptibly() {
  Node node = addConditionWaiter();
  int savedState = fullyRelease(node);
  boolean interrupted = false;
  while (!isOnSyncQueue(node)) {
    LockSupport.park(this);
    if (Thread.interrupted()) interrupted = true;
  }
  if (acquireQueued(node, savedState) || interrupted) selfInterrupt();
}
因此,等待是在循环中完成的,这将消除在该函数外部循环的需要

但是请记住,这也意味着
Thread.interrupt()
不会执行任何操作,这可能会导致代码的某些锁定,即在关机期间。

以下操作:

不间断地等待()

使当前线程等待,直到发出信号。 与此条件相关联的锁将自动释放,当前线程出于线程调度目的被禁用,并处于休眠状态,直到发生以下三种情况之一:

  • 其他一些线程为此条件调用
    signal()
    方法,而当前线程恰好被选择为要唤醒的线程;或
  • 其他一些线程为此条件调用
    signalAll()
    方法;或
  • 出现“虚假唤醒”
因此,中断不在可能的唤醒条件列表中,但虚假唤醒是。不要让您通过查看特定的实现代码来指导。应用程序最终运行的实现可能完全不同

此外,
条件
是一个
接口
,即使在一个运行时环境中也可能有不同的实现。甚至没有指定此代码来自哪个具体类

您必须使用通常的循环
waitunterruptibly()
执行等待操作

考虑以下几点:

  • 信号和等待之间没有1:1映射,
    • 因此,您可能会错过线程唤醒前发生的一个或多个信号
    • 更糟糕的是,当信号发生在另一个线程开始等待之前时,它们不会被记住,因此会丢失
  • 因此,在决定等待之前,必须预先检查所需的条件状态
  • 这意味着一个信号可能会唤醒一个线程,但另一个线程由于预检查成功而消耗状态,因此被唤醒的线程必须重新检查所需的条件状态
因此,即使没有虚假的唤醒,也需要在等待前进行预检查,并在唤醒后重新检查的循环。

不间断地等待()

使当前线程等待,直到发出信号。 与此条件相关联的锁将自动释放,当前线程出于线程调度目的被禁用,并处于休眠状态,直到发生以下三种情况之一:

  • 其他一些线程为此条件调用
    signal()
    方法,而当前线程恰好被选择为要唤醒的线程;或
  • 其他一些线程为此条件调用
    signalAll()
    方法;或
  • 出现“虚假唤醒”
因此,中断不在可能的唤醒条件列表中,但虚假唤醒是。不要让您通过查看特定的实现代码来指导。应用程序最终运行的实现可能完全不同

此外,
条件
是一个
接口
,即使在一个运行时环境中也可能有不同的实现。甚至没有指定此代码来自哪个具体类

您必须使用通常的循环
waitunterruptibly()
执行等待操作

考虑以下几点:

  • 信号和等待之间没有1:1映射,
    • 因此,您可能会错过线程唤醒前发生的一个或多个信号
    • 更糟糕的是,当信号发生在另一个线程开始等待之前时,它们不会被记住,因此会丢失
  • 因此,在决定等待之前,必须预先检查所需的条件状态
  • 这意味着一个信号可能会唤醒一个线程,但另一个线程由于预检查成功而消耗状态,因此被唤醒的线程必须重新检查所需的条件状态

因此,即使没有虚假唤醒,也需要一个循环,在等待前进行预检查,在唤醒后重新检查。

中断不是虚假唤醒,它们仍然可能发生。@PeterLawrey调用waitingunterruptibly()的线程是否会继续等待,直到发出信号,不需要在一个循环中?只有在它没有虚假地醒来的情况下。@PeterLawrey感谢你的解谜。现在了解到,建议我们调用任何