Reputation: 1187
While I am reading java.util.concurrent.locks.Condition
API documentation,
I see that:
When waiting upon a Condition, a "spurious wakeup" is permitted to occur, in general, as a concession to the underlying platform semantics. This has little practical impact on most application programs as a Condition should always be waited upon in a loop, testing the state predicate that is being waited for. An implementation is free to remove the possibility of spurious wakeups but it is recommended that applications programmers always assume that they can occur and so always wait in a loop
and the awaitUninterruptibly() says:
If the current thread's interrupted status is set when it enters this method, or it is interrupted while waiting, it will continue to wait until signalled. When it finally returns from this method its interrupted status will still be set
So, does it mean that we don't need to invoke awaitUninterruptibly() in loop ? Please clarify. Thanks in advance.
Upvotes: 1
Views: 1578
Reputation: 298429
The specification is pretty clear:
void awaitUninterruptibly()
Causes the current thread to wait until it is signalled. The lock associated with this condition is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:
- Some other thread invokes the
signal()
method for this Condition and the current thread happens to be chosen as the thread to be awakened; or- Some other thread invokes the
signalAll()
method for this Condition; or- A "spurious wakeup" occurs.
So, interrupting is not on the list of possible wakeup conditions but spurious wakeup are. Don’t let you guide by looking into a particular piece of implementation code. The implementation your application finally runs on might be entirely different.
Further, Condition
is an interface
which might have different implementations even within one runtime environment. This answer doesn’t even specify which concrete class this code is from.
You have to perform the wait operation using the usual loop with awaitUninterruptibly()
.
Consider the following:
Therefore, even without spurious wakeups a loop which pre-checks before waiting and re-checks after waking up is necessary.
Upvotes: 3
Reputation: 14289
From the code:
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();
}
So the waiting is done in a loop, which would remove the need to loop that outside this function.
However keep in mind that this also means that Thread.interrupt()
won't do anything, which might lead to certain lock-ups of your code, i.E. during shutdown.
Upvotes: 2