当我阅读java.util.concurrent.locks.Condition API文档时,
我看到:
在等待条件时,通常允许出现“虚假唤醒”,作为对底层平台语义的让步。这对大多数应用程序几乎没有实际影响,因为应该始终在循环中等待条件,测试等待的状态谓词。实现可以自由地消除出现虚假唤醒的可能性,但建议应用程序程序员始终假定它们可以发生,因此总是在循环中等待。
awaitUninterruptibly()说:
如果当前线程的中断状态是在它进入此方法时设置的,或者它在等待时被中断,则它将继续等待直到发出信号。当它最终从该方法返回时,它的中断状态仍将被设置。
那么,这是否意味着我们不需要在循环中调用awaitUninterruptibly() ?请澄清。提前谢谢。
发布于 2015-01-14 10:15:54
根据守则:
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()不会做任何事情,这可能会导致代码的某些锁,即在关闭期间。
发布于 2015-01-16 12:04:36
The 规格很清楚
void awaitUninterruptibly()导致当前线程等待,直到发出信号。与此条件关联的锁被原子释放,当前线程将被禁用以用于线程调度,并处于休眠状态,直到发生以下三种情况之一:
signal()方法,而当前线程恰好被选择为要唤醒的线程;或signalAll()方法;或因此,中断并不在可能的唤醒条件列表中,而是虚假的唤醒条件列表中。不要让您通过查看特定的实现代码来进行指导。您的应用程序最终运行的实现可能完全不同。
此外,Condition是一个interface,即使在一个运行时环境中也可能有不同的实现。这个答案甚至没有指定这段代码来自哪个具体类。
您必须使用通常的awaitUninterruptibly()循环来执行等待操作。
请考虑以下几点:
因此,即使没有虚假的唤醒,在等待之前预先检查,醒来后再检查的循环也是必要的。
https://stackoverflow.com/questions/27938145
复制相似问题