17 ms·
Here are my guesses. 1. Same as with normal threads: CompletableFuture<Foo> future = new CompletableFuture<>(); someApiThatTakesACallback(future::complete
by twic 5y ago
Here are my guesses.
1. Same as with normal threads:
CompletableFuture<Foo> future = new CompletableFuture<>();
someApiThatTakesACallback(future::complete);
Foo result = future.get(); // this can take a timeout
2. If you mean that the operations are blocking and should be called in parallel using virtual threads, the equivalent of Promise.any::
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
Future<Foo> future1 = executor.submit(this::doSomething1);
Future<Bar> future2 = executor.submit(this::doSomething2);
Foo result1 = future1.get();
Bar result2 = future2.get();
There is a version of that using ExecutorService::invokeAll, but i'm not sure it's any more concise, because you still need to unpack the futures one by one.
For Promise.any:
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
Foo result = executor.invokeAny(List.of(this::doSomething1, this::doSomething2));
The asymmetry between invokeAny and invokeAll here is slightly grating, but makes sense.
Note that in both cases, you probably already have an executor lying around that you can use for this.
- binarynate 5y agoThanks! Your examples are super helpful.
- samus 5y agoDo note that the `Executor` interface now extends `AutoCloseable` and can now be used with the `try-with-resources`-statement. This is the most important building block for the new Structured Concurrency approach!