Object.wait returns normally if interrupted

Pavel Rappo pavel.rappo at gmail.com
Fri Jun 27 12:11:20 UTC 2025


So, Object.wait() guarantees to throw InterruptedException if the
interrupt status is set upon entrance, yes? Could this be added to
javadoc?

On Fri, Jun 27, 2025 at 12:59 PM David Holmes <david.holmes at oracle.com> wrote:
>
> On 27/06/2025 5:58 pm, Pavel Rappo wrote:
> > David,
> >
> > As you correctly identified, the edge case that I mentioned is this:
> > concurrent interrupt and notify [^1]. It has nothing to do with
> > spurious wake-ups or virtual threads. In fact, I've seen that with
> > virtual threads Object.wait behaves exactly the same way as with
> > platform threads in that regard. So I cannot report any issue here.
> >
> > I'm only asking about the accuracy of the javadoc contract. Say, a
> > programmer uses this template from Object.wait's javadoc.
> >
> >      synchronized (obj) {
> >          while ( <condition does not hold and timeout not exceeded> ) {
> >              long timeoutMillis = ... ; // recompute timeout values
> >              int nanos = ... ;
> >              obj.wait(timeoutMillis, nanos);
> >          }
> >          ... // Perform action appropriate to condition or timeout
> >      }
> >
> > Obviously, the programmer handles InterruptedException outside this
> > template. Perhaps the programmer relies on that exception being thrown
> > on an interrupt. So they think of this code as of interruptible.
> >
> > Now, if it is generally possible -- and not just in this edge case --
> > for Object.wait to return from an interrupt normally, the above code
> > is effectively uninterruptible. And the programmer does not know about
> > it. To fix that code, the programmer needs to additionally and
> > explicitly check the interrupt status.
>
> The wait() will throw IE on the next loop if the condition is not met.
> Otherwise the code proceeds with the knowledge the thread was notified,
> irrespective of whether the thread was also interrupted "around the same
> time".
>
> David
> -----
>
> > In contrast, j.u.c.Condition.await, makes a special provision, which
> > guarantees that if the method returns normally from an interrupt, it
> > will throw an exception on the next iteration of the
> > j.u.c.{Lock,Condition} analogue of the above template:
> >
> >> If the current thread:
> >>
> >> has its interrupted status set on entry to this method;
> >> or ...
> >> then InterruptedException is thrown and the current thread's interrupted status is cleared.
> >
> > [^1]: https://docs.oracle.com/javase/specs/jls/se24/html/jls-17.html#jls-17.2.4
> >
> > On Fri, Jun 27, 2025 at 3:47 AM David Holmes <david.holmes at oracle.com> wrote:
> >>
> >> Hi Pavel,
> >>
> >> On 27/06/2025 8:23 am, Pavel Rappo wrote:
> >>> Here's an interesting behaviour. A thread that has been blocked in
> >>> Object.wait is interrupted. But instead of throwing an
> >>> InterruptedException, Object.wait returns normally with the thread's
> >>> interrupt status set.
> >>
> >> Do you mean it returns normally without being notified? That's allowed
> >> by spec as it is just a spurious wakeup.
> >>
> >> That said, it shouldn't really happen in the current implementation
> >> AFAIK, though with recent changes around virtual thread support it is
> >> possible some new edge case has crept in. Or a bug.
> >>
> >> If the interrupt is racing with a notification then what you see is also
> >> allowed as you can't tell which occurred first:
> >>
> >> "If the current thread is interrupted by any thread before or while it
> >> is waiting, ...
> >>
> >> once notified it is no longer waiting.
> >>
> >>> This behaviour is not mentioned in javadoc, yet I witnessed it.
> >>> Granted, I could only trigger it in an edge case described in JLS. I
> >>
> >> What edge case is described in current JLS?
> >>
> >>> wonder if the behaviour is reserved for that edge case, or it can be
> >>> observed elsewhere and there is a genuine gap in javadoc. FWIW,
> >>> javadoc for j.u.c.Condition documents this behaviour.
> >>>
> >>> Here's a practical implication of this. If some code that uses
> >>> Object.wait wants to be interruptible, it must not rely on Object.wait
> >>> to throw InterruptedException. It should check interrupt status or
> >>> call other methods that are guaranteed to throw InterruptedException
> >>> on thread interruption.
> >>
> >> In typical usage though if you were notified as well then responding to
> >> that is generally fine and is what would happen if the notification
> >> definitely occurred before the interrupt. If it was a spurious wakeup
> >> then you should be re-waiting in a loop and the next wait will throw the
> >> IE. So I think no real code would be adversely impacted by these edge cases.
> >>
> >> Cheers,
> >> David
> >> -----
> >>
> >>> -Pavel
> >>
>


More information about the core-libs-dev mailing list