Maxim Karvonen wrote:There is a possibility of spurious wakeups when a thread ends waiting without any visible reason. And in your case it is almost definitely a "spurious wakeups" because you wait on a thread object. There may be JVM notifications on a thread lifetime events. For example, thread termination may wake up all other threads waiting on it (similar to a notifyAll() call).
First, the reason
Java mentions "spurious wakeups" in the specification, is because the threading system sits on top of the native threading systems. And today, most threading systems has issues with spurious wakeups. So, what is spurious wakeups? As mentioned, it is the thread waking up without a notification ... but interestingly, it is *not* common. In most cases, it is merely that way because the native threading system can't make the guarantee. In other words, spurious wakeups should be rare, if they ever happen at all.
So, if spurious wakeups shouldn't really be happening, what is this exactly? The reason is due to hitting a conflict (which is due to implementation detail). Unfortunately, the thread object is already in use as a notification object. The core java library uses the thread object to wake up threads doing a join(). When any thread completes, as part of the clean up process, a notifyAll() is done to wake up the threads waiting to join().
So, when the thread completed, a notification is sent, and your waiting thread also woke up. Arguably, this is just like a spurious wakeup, in that it is waking up unexpectedly, but it is not really the same "spurious wakeup" that the JLS is referring to.
Henry