<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From: </b>"David Alayachew" <davidalayachew@gmail.com><br><b>To: </b>"Alan Bateman" <alan.bateman@oracle.com><br><b>Cc: </b>"Remi Forax" <forax@univ-mlv.fr>, "loom-dev" <loom-dev@openjdk.java.net><br><b>Sent: </b>Wednesday, September 24, 2025 9:06:41 PM<br><b>Subject: </b>Re: Remark on the StructuredTaskScope API of Java 25<br></blockquote></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><div dir="ltr"><div class="gmail_default" style="font-family: monospace;" data-mce-style="font-family: monospace;">> If the API allowed Subtask::get to be used<br>> before join then it would be very fragile as it<br>> would be like a "wait-less" Future::get. It<br>> might work sometimes, but if a subtask were<br>> slow then Subtask::get would throw ISE.<br><br>Can you explain this in more detail? I don't understand what you are saying here.</div></div></blockquote><div><br></div><div>Actually, you can not extract the values using the main from any subtasks until STS.join() complete,</div><div>there is a specail check is Subtask.get() that check that if you are the main thread, join has to be called before.</div><div><br></div><div>So if you write,</div><div><br></div><div> try(var sts = STS.open()) {</div><div> var subtask = sts.fork(callable); </div><div><br></div><div> // we are before the join here</div><div> IO.println(subtask.get());</div><div> // here you have a race between the main thread and the virtual thread that run the callable</div><div> // so you can get spurious IllegalStateException</div><div> // 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()</div><div> </div><div> sts.join();</div><div><br></div><div> IO.println(subtask.get()); // this is fine, we are after the join().</div><div> }</div><div><br></div><div><br data-mce-bogus="1"></div><div>The problem, is that this check is a kind of weak, because you can write</div><div><br></div><div><div>try(var sts = STS.open()) {</div><div> var subtask = sts.fork(callable); </div><div><br data-mce-bogus="1"></div><div> // spurious STS are back !</div><div> Thread.ofVirtual().start(() -> IO.println(subtask.get())).join();</div><div><br data-mce-bogus="1"></div><div> sts.join();</div><div> }</div></div><div><br></div><div>regards,</div><div>Rémi</div><div><br></div><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, Sep 24, 2025 at 1:52 PM Alan Bateman <<a href="mailto:alan.bateman@oracle.com" target="_blank" rel="noopener" data-mce-href="mailto:alan.bateman@oracle.com">alan.bateman@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left: 1px solid #cccccc; padding-left: 1ex;" data-mce-style="margin: 0px 0px 0px 0.8ex; border-left: 1px solid #cccccc; padding-left: 1ex;"><div><br><br><div>On 24/09/2025 16:37, Remi Forax wrote:<br></div><blockquote><pre>:
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).</pre></blockquote><br>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.<br><br><blockquote><pre> - 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() ?
</pre></blockquote>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?<br><br>-Alan<br></div></blockquote></div><br></blockquote></div></div></body></html>