New candidate JEP: 462: Structured Concurrency (Second Preview)

Josiah Noel josiahnoel at gmail.com
Fri Oct 27 17:16:11 UTC 2023


Have you tried it out? Trying this stuff out is the best way to see how it
works, in any case, observe the following example

try (ShutdownOnSuccess<Integer> scope = new StructuredTaskScope.
ShutdownOnSuccess<>()) {


var fail =

scope.fork(

() -> {

throw new IllegalAccessException();

});


scope.fork(

() -> {

Thread.sleep(Duration.of(random.nextInt(0, 1000), ChronoUnit.MILLIS));

return 1;

});


scope.fork(

() -> {

Thread.sleep(Duration.of(random.nextInt(0, 1000), ChronoUnit.MILLIS));

return 2;

});


scope.join();

// get first result, (will not care about exceptions as long as one
succeeds)

scope.result();


// will throw an exception

fail.get();

}


Essentially, you must use the `scope.result()` method to retrieve the
result instead of calling the get methods on a particular subtask

On Fri, Oct 27, 2023 at 12:37 PM Eric Kolotyluk <eric at kolotyluk.net> wrote:

> Looks good... thanks.
>
> One slight area of confusion for me was,
>
> <T> List<Future<T>> executeAll(List<Callable<T>> tasks)
>         throws InterruptedException {
>     try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
>     	  List<? extends Supplier<Future<T>>> futures = tasks.stream()
>     	      .map(task -> asFuture(task))
>      	      .map(scope::fork)
>      	      .toList();
>     	  scope.join();
>     	  return futures.stream().map(Supplier::get).toList();
>     }
> }
>
> static <T> Callable<Future<T>> asFuture(Callable<T> task) {
>    return () -> {
>        try {
>            return CompletableFuture.completedFuture(task.call());
>        } catch (Exception ex) {
>            return CompletableFuture.failedFuture(ex);
>        }
>    };
> }
>
> And what happens if ShutdownOnSuccess is called instead. Eventually I
> reasoned that the right thing should happen, but there should only ever be
> one element in the list. Does the scope guarantee only one result?
>
>    1. It would be slightly helpful to point this out in a note so that it
>    is more obvious.
>    2. What is less obvious is that with ShutdownOnSuccess what happens if
>    one or more of the siblings throw an exception?
>       - I would hope that so long at least one task succeeds, this should
>       not cause the overall success of the scope to fail.
>       - It would be nice to see this explained more clearly.
>       -  Maybe ShutdownOnSuccess deserves its own example, discussing
>       possible edge cases.
>
> Somehow I am remembering Scala 'for comprehensions' with concurrent tasks
> that 'yield' a result... 😉
>
> The current situation seems kinda clunky with using one stream to collect
> futures, and yet another stream to collect results. Maybe one of the Java
> architects hates such boilerplate, and will come up with an elegant way to
> reduce/remove such boilerplate.
>
> Sincerely, Eric
> On 2023-10-27 7:39 a.m., Mark Reinhold wrote:
>
> https://openjdk.org/jeps/462
>
>   Summary: Simplify concurrent programming by introducing an API for
>   structured concurrency. Structured concurrency treats groups of related
>   tasks running in different threads as a single unit of work, thereby
>   streamlining error handling and cancellation, improving reliability,
>   and enhancing observability. This is a preview API.
>
> - Mark
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20231027/c3a2fee9/attachment-0001.htm>


More information about the loom-dev mailing list