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感谢你的解谜。现在了解到,建议我们调用任何