> From: "David Alayachew" <[email protected]>
> To: "Alan Bateman" <[email protected]>
> Cc: "Remi Forax" <[email protected]>, "loom-dev" <[email protected]>
> 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:[email protected]
> | [email protected] ] > 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

Reply via email to