Rethinking Exceptions in the Context of Loom and Structured Concurrency

Attila Kelemen attila.kelemen85 at gmail.com
Wed Dec 24 11:54:59 UTC 2025


>
> InterruptedException is special, making it unchecked would make it more
> hazardous than it is already. This is because throwing InterruptedException
> clears the interrupted status. If you catch the exception then you must
> remember to reset the interrupted status when continuing without
> re-throwing the exception. This ensures that code that executes
> subsequently can also respond to the request to finish up.
>

It would have been better if InterruptedException would be in its own
unchecked hierarchy (i.e. not an `Exception`), but likely that would be too
big of a breaking change now. Today's reality is that you can rest assured
that some code you are calling will clear the interrupted status (in a
better case throwing some unknown exception type instead). That is, thread
interrupts are completely unreliable, I had the unluck to go into the
nightmare of it, and design a lot of APIs around it where I simply treat
`InterruptedException` as a bug (aside from low level APIs designed for
it). It is way more pleasant than thread interrupts.

As regards STS.join throwing InterruptedException then it shouldn't be a
> surprise. The other APIs in this area do the same. We know InterruptedException
> and the interrupted status are hard to use. There are some ideas for
> making the existing thread interruption mechanism easier to use but nothing
> close to a proposal/JEP at this time.
>

I also had much-much time in this area - including implementations which
work in production for many-many years now -, so I would most certainly be
interested in those discussions. Which list would be used for it, if it
happens?

Though the JDK is in a more difficult spot than I was when it comes to
implementing it, I would say a sensible approach would be the following:

1. Declare an unchecked `OperationCancelledException` (it is actually worth
considering to make it its own unchecked hierarchy rather than
`RuntimeException` (I mean not even `Exception`), though there are some
obvious downsides), a `CancellationToken` and a `CancellationController`
(with relatively obvious roles). Though there are some very non-obvious
gotchas implementing them as I have learned in the past.

2. Have a dedicated scoped value (maybe even specially stored for
efficiency?) storing a `CancellationToken`.

3. Provide a utility method `handleCancellationInterrupt` which could be
called in a catch of `InterruptedException` or simply when detecting
interrupts.

4. Create alternatives to methods throwing `InterruptedException` which
rely on the new cancellation mechanism. E.g.: `await` -> `awaitCancelably`.

Attila
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20251224/4ad9da98/attachment.htm>


More information about the loom-dev mailing list