Advanced concurrency
advconcurrency7StructuredConcurrency
- Path
- pkg16advconcurrency/advconcurrency7StructuredConcurrency.java
- Package
- pkg16advconcurrency
- Study order
- 7
- Run
- Single-file source launch
- Command
- java pkg16advconcurrency/advconcurrency7StructuredConcurrency.java
- Example
- Stable demo; Java 25 preview API is only in the comment
- Requires
- Java 8
There is no in-browser runner. This is the file from the curriculum, unchanged.
1package pkg16advconcurrency;2 3import java.util.concurrent.CompletableFuture;4import java.util.concurrent.TimeUnit;5 6/*7 * advconcurrency7StructuredConcurrency.java8 * -----------------------------------------9 * The main method uses CompletableFuture. That code needs Java 8 and does not10 * use --enable-preview.11 *12 * Structured concurrency is still a preview in Java 25 (JEP 505). It is not13 * final. A program that calls it must be compiled and run with --enable-preview.14 * Java 25 opens a scope with StructuredTaskScope.open and a Joiner. It does not15 * use a public constructor:16 *17 * try (var scope = StructuredTaskScope.open(18 * StructuredTaskScope.Joiner.<String>anySuccessfulResultOrThrow())) {19 * scope.fork(() -> fetchFrom("primary", 200));20 * scope.fork(() -> fetchFrom("backup", 50));21 * return scope.join();22 * }23 *24 * Earlier previews used a public constructor. That shape is not the Java 25 API.25 */26public class advconcurrency7StructuredConcurrency {27 28 static String fetchFrom(String source, int delayMs) throws InterruptedException {29 Thread.sleep(delayMs);30 return "data-from-" + source;31 }32 33 public static void main(String[] args) throws Exception {34 // Failover race: first successful result wins (CompletableFuture stable equivalent)35 CompletableFuture<String> primary = CompletableFuture.supplyAsync(() -> {36 try { return fetchFrom("primary", 200); } catch (InterruptedException e) {37 Thread.currentThread().interrupt(); throw new RuntimeException(e);38 }39 });40 CompletableFuture<String> backup = CompletableFuture.supplyAsync(() -> {41 try { return fetchFrom("backup", 50); } catch (InterruptedException e) {42 Thread.currentThread().interrupt(); throw new RuntimeException(e);43 }44 });45 46 String winner = primary.applyToEither(backup, s -> s)47 .get(1, TimeUnit.SECONDS);48 System.out.println("Race winner: " + winner);49 50 // All must succeed in parallel51 CompletableFuture<String> db = CompletableFuture.supplyAsync(() -> {52 try { return fetchFrom("db", 30); } catch (InterruptedException e) {53 Thread.currentThread().interrupt(); throw new RuntimeException(e);54 }55 });56 CompletableFuture<String> cache = CompletableFuture.supplyAsync(() -> {57 try { return fetchFrom("cache", 20); } catch (InterruptedException e) {58 Thread.currentThread().interrupt(); throw new RuntimeException(e);59 }60 });61 System.out.println("Parallel: " + db.get() + " + " + cache.get());62 }63}