Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do spurious wakeups in Java actually happen?

People also ask

Do spurious wakeups actually happen?

Because spurious wakeups can happen whenever there's a race and possibly even in the absence of a race or a signal, when a thread wakes on a condition variable, it should always check that the condition it sought is satisfied.

What are spurious wakeup in Java?

A spurious wakeup means a thread is woken up even though no signal has been received. Spurious wakeups are a reality and are one of the reasons why the pattern for waiting on a condition variable happens in a while loop as discussed in earlier chapters.

How do you deal with spurious wakeup?

Either 1 or 3 way is fine for dealing with spurious wakeups (assuming that full modification is protected by the same mutex) except you get predicate condition wrong, it should be: unique_lock<mutex> ul(m); cv. wait(ul, [&](){return full;}); to make this code equal to variant 1.


The Wikipedia article on spurious wakeups has this tidbit:

The pthread_cond_wait() function in Linux is implemented using the futex system call. Each blocking system call on Linux returns abruptly with EINTR when the process receives a signal. ... pthread_cond_wait() can't restart the waiting because it may miss a real wakeup in the little time it was outside the futex system call. This race condition can only be avoided by the caller checking for an invariant. A POSIX signal will therefore generate a spurious wakeup.

Summary: If a Linux process is signaled its waiting threads will each enjoy a nice, hot spurious wakeup.

I buy it. That's an easier pill to swallow than the typically vague "it's for performance" reason often given.


I have a production system that exhibits this behaviour. A thread waits on a signal that there is a message in the queue. In busy periods, up to 20% of the wakeups are spurious (ie when it wakes there is nothing in the queue). This thread is the only consumer of the messages. It runs on a Linux SLES-10 8-processor box and is built with GCC 4.1.2. The messages come from an external source and are processed asynchronously because there are problems if my system does not read them fast enough.


To answer the question in the titile - Yes! it does happen.Though the Wiki article mentions a good deal about spurious wakeups a nice explanation for the same that I came across is as follows -

Just think of it... like any code, thread scheduler may experience temporary blackout due to something abnormal happening in underlying hardware / software. Of course, care should be taken for this to happen as rare as possible, but since there's no such thing as 100% robust software it is reasonable to assume this can happen and take care on the graceful recovery in case if scheduler detects this (eg by observing missing heartbeats).

Now, how could scheduler recover, taking into account that during blackout it could miss some signals intended to notify waiting threads? If scheduler does nothing, mentioned "unlucky" threads will just hang, waiting forever - to avoid this, scheduler would simply send a signal to all the waiting threads.

This makes it necessary to establish a "contract" that waiting thread can be notified without a reason. To be precise, there would be a reason - scheduler blackout - but since thread is designed (for a good reason) to be oblivious to scheduler internal implementation details, this reason is likely better to present as "spurious".

I was reading this answer from Source and found it reasonable enough. Also read

Spurious wakeups in Java and how to avoid them.

PS: Above link is to my personal blog that has additional details about spurious wakeups.


Cameron Purdy wrote a blog post a while back about being hit by the spurious wakeup problem. So yes, it happens

I'm guessing it's in the spec (as a possibility) because of limitations of some of the platforms which Java gets deployed on? although I may be wrong!


Just to add this. Yes it happens and I spent three days searching for the cause of a multi-threading problem on a 24 core machine (JDK 6). 4 of 10 executions experienced that without any pattern. This never happened on 2 core or 8 cores.

Studied some online material and this is not a Java problem but a general rare but expected behavior.