<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    On 12/04/2023 10:23, Daniel Schmid wrote:<br>
    <blockquote type="cite" cite="mid:bf216dba-bbfc-2692-969f-50b57a4ece0d@wwwmaster.at">
      
      <p>Hi,<br>
      </p>
      <p>JEP 437 (Structured Concurrency) mentions the following:</p>
      <p>> Every fork runs in its own newly created thread, which by
        default is a virtual thread. The forks' threads are owned by the
        scope, which in turn is owned by its creating thread, thus
        forming a hierarchy. Any fork can create its own nested
        StructuredTaskScope to fork its own subtasks, thus extending the
        hierarchy. That hierarchy is reflected in the code's block
        structure, which confines the lifetimes of the forks: All of the
        forks' threads are guaranteed to have terminated once the scope
        is closed, and no thread is left behind when the block exits.</p>
      <p>So, the forked tasks are running using virtual threads.
        However, I didn't understand which platform threads are chosen
        as carriers in case the owning thread is a platform thread.<br>
        Would that use the default virtual thread pool for selecting
        carrier threads? If that were the case, would that block the
        platform thread owning the StructuredTaskScope?<br>
        Or would it use the owning platform thread as the carrier thread
        or include that in the selection of carrier threads?<br>
      </p>
      <p>For example, take the following piece of code from JEP 437:</p>
      <pre>Response handle() throws ExecutionException, InterruptedException {
    try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
        Future<String>  user  = scope.fork(() -> findUser());
        Future<Integer> order = scope.fork(() -> fetchOrder());

        scope.join();           // Join both forks
        scope.throwIfFailed();  // ... and propagate errors

        // Here, both forks have succeeded, so compose their results
        return new Response(user.resultNow(), order.resultNow());
    }
}
</pre>
      <p>If we assume this method is called from a platform thread,
        which threads would be eligible as carrier threads for the tasks
        created for findUser() and fetchOrder()? The platform-thread
        calling handle, the platform threads from the virtual thread
        pool or both?<br>
      </p>
    </blockquote>
    You shouldn't need to be concerned with carrier threads in these
    examples. The no-arg constructor creates a ShutdownOnFailure that
    creates virtual threads so in the example, the scope.join called
    from platform thread T is waiting for two virtual threads to finish
    the two tasks. There's no relationship between T and the carrier
    threads used in the virtual thread implementation. T can execute
    concurrently with the virtual threads.<br>
    <br>
    -Alan<br>
  </body>
</html>