Remark on the StructuredTaskScope API of Java 25
forax at univ-mlv.fr
forax at univ-mlv.fr
Thu Sep 25 05:38:41 UTC 2025
> From: "David Alayachew" <davidalayachew at gmail.com>
> To: "Alan Bateman" <alan.bateman at oracle.com>
> Cc: "Remi Forax" <forax at univ-mlv.fr>, "loom-dev" <loom-dev at openjdk.java.net>
> Sent: Wednesday, September 24, 2025 9:06:41 PM
> Subject: Re: Remark on the StructuredTaskScope API of Java 25
> > If the API allowed Subtask::get to be used
> > before join then it would be very fragile as it
> > would be like a "wait-less" Future::get. It
> > might work sometimes, but if a subtask were
> > slow then Subtask::get would throw ISE.
> Can you explain this in more detail? I don't understand what you are saying
> here.
Actually, you can not extract the values using the main from any subtasks until STS.join() complete,
there is a specail check is Subtask.get() that check that if you are the main thread, join has to be called before.
So if you write,
try(var sts = STS.open()) {
var subtask = sts.fork(callable);
// we are before the join here
IO.println(subtask.get());
// here you have a race between the main thread and the virtual thread that run the callable
// so you can get spurious IllegalStateException
// to make the user aware of that, SubTask.get() has a special case that throw is get() is called by the main thread before join()
sts.join();
IO.println(subtask.get()); // this is fine, we are after the join().
}
The problem, is that this check is a kind of weak, because you can write
try(var sts = STS.open()) {
var subtask = sts.fork(callable);
// spurious STS are back !
Thread.ofVirtual().start(() -> IO.println(subtask.get())).join();
sts.join();
}
regards,
Rémi
> On Wed, Sep 24, 2025 at 1:52 PM Alan Bateman < [ mailto:alan.bateman at oracle.com
> | alan.bateman at oracle.com ] > wrote:
>> On 24/09/2025 16:37, Remi Forax wrote:
>>> :
>>> And now two remarks,
>>> - is there a way to remove the limitation that the main thread (the one that
>>> have created the STS) can not access to SubTask.get(),
>>> because there is at least a case where i know that the task is finished before
>>> join() is called (see below).
>> This restriction is there to ensure that the API is used as intended. Subtasks
>> are forked individually and then joined as a unit. If the API allowed
>> Subtask::get to be used before join then it would be very fragile as it would
>> be like a "wait-less" Future::get. It might work sometimes, but if a subtask
>> were slow then Subtask::get would throw ISE.
>>> - is there a way to get a joiner that returns the list of subtask in the order
>>> if their completeness, not in the order of onFork() ?
>> A Joiner can collect in its onComplete method so that will give you completion
>> order. That said, I suspect you might be asking something different. Are you
>> thinking about APIs such as CompletionService where you get a wakeup as
>> subtasks complete rather join as a unit?
>> -Alan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20250925/d5972052/attachment-0001.htm>
More information about the loom-dev
mailing list