JEP 425 (Virtual Threads) - Cancellation

David Holmes david.holmes at oracle.com
Mon May 2 05:17:28 UTC 2022


On 2/05/2022 8:04 am, Attila Kelemen wrote:
> Hi,
> 
> Since the virtual threads API is currently incubating, I do support that
> it should be released (as incubating in Java 19). However, I would
> like to propose that a better, more robust cancellation mechanism is to
> be provided with it (as some kind of companion JEP) in future releases
> before the non-incubating release.
> 
> I've always considered the interrupt based cancellation to be very fragile
> for various reasons, and I think that the new virtual thread release would
> be a very safe time to fix the lack of proper cancellation mechanism in
> Java. If it is not fixed before the official release of this JEP, then I fear
> that it is less likely to be fixed, due to more compatibility issues. Or if a
> new cancellation mechanism will not be released with it, then at least
> define the way it is planned to be added in the future to ensure that there
> won't be any issues adding it later. The only document I have found
> referring to this topic was:
> https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2.html
> but it doesn't attempt to address it.
> 
> While the cheapness of virtual threads does somewhat solve the issue
> of canceling only subtasks by allowing me to start a virtual thread with little
> cost, and interrupt it separately, it does not solve other issues. One big
> pain of mine is that blocking I/O is often uninterruptible (and not even
> cancelable by other means), and as far as I understand, this won't change.

The issue with interruptible I/O has little to do with the 
interrupt-mechanism per-se. While traditional thread use of blocking I/O 
operations can not be "interrupted" this is because the underlying I/O 
primitives do not support cancellation. With virtual threads using 
non-blocking I/O operations under the covers it would be trivial to 
provide a means to unblock threads blocked on I/O - but that is the not 
hard part of "interruptible I/O". The hard part is "what does cancelling 
an I/O operation do to the underlying file/stream/device?". When the NIO 
API's were introduced they had to consider this question when 
InterruptibleChannels were defined - and the answer was "interrupting a 
thread blocked on a channel I/O operation closes the channel". It was 
the only reasonably sane thing to do. So the issue with interruptible 
I/O is not the interrupt mechanism as such, nor the use of platform 
versus virtual threads, but whether the I/O API actually supports a 
model of cancellation itself - which the core API's (non-NIO) do not.**

**InterruptibleIOException was a failed attempt to provide this but it 
only handled the unblocking of the thread, not the effects on the 
underlying I/O object. And it could only be implemented on platforms 
that provided a low-level I/O cancellation mechanism - which was only 
Solaris at the time.

I think Loom's "structured concurrency" (future JEP) may provide more 
support in this area but I'll let the Loom folk speak to that.

Cheers,
David

> One solution would be of course is to allow providing the virtual threads
> a cancellation token upon creation, and let the virtual thread scheduler to
> throw a `VirtualThreadCancelledException` (or something similar) in some
> well defined cases (definitely not just at any safepoint). Of course, this
> exception has to be unchecked, and preferably not extend `Exception`
> to avoid people wrapping it left and right. With this the current interruption
> mechanism could be deprecated as well.
> 
> Can we expect a similar cancellation mechanism to be considered?
> 
> Thanks,
> Attila


More information about the jdk-dev mailing list