Skip to content

Instantly share code, notes, and snippets.

@CattenLinger
Last active April 24, 2025 18:01
Show Gist options
  • Select an option

  • Save CattenLinger/3b2fbcbea7b3e3eaf4dbc2b8ba841596 to your computer and use it in GitHub Desktop.

Select an option

Save CattenLinger/3b2fbcbea7b3e3eaf4dbc2b8ba841596 to your computer and use it in GitHub Desktop.
To concurrently get only the fastest result with CompletableFuture in Java.
import java.util.Random;
import java.util.concurrent.*;
public class FastestResultPlayground {
static void sleep(long millis) {
try {
// Simulating a heavy job
Thread.sleep(millis);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static final Random random = new Random();
// By default JVM uses ForkJoinPool to do async jobs.
// This settings is optional
static final ExecutorService executor = ForkJoinPool.commonPool();
static CompletableFuture<String> createDemoJob(int index, CompletableFuture<String> yield) {
return CompletableFuture.supplyAsync(() -> {
final long ms = random.nextInt(10_000);
System.out.println("Created job " + index + " Sleep " + ms + " @T:" + Thread.currentThread().getName());
sleep(ms);
return String.valueOf(index);
}, executor).whenComplete((result, ex) -> { // i: Chain calling returns different Future instance.
// Completed Future will returns 'false', Future.isDone() is not necessary
if (yield.complete(result)) return;
System.out.println("Job Canceled. @T:" + Thread.currentThread().getName());
});
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
final CompletableFuture<String> firstSucceedFuture = new CompletableFuture<>();
// You can create only 1 job to see what will happend.
final CompletableFuture<Void> allCompletedFuture = CompletableFuture.allOf(
createDemoJob(0, firstSucceedFuture),
createDemoJob(1, firstSucceedFuture),
createDemoJob(2, firstSucceedFuture)
).whenComplete((result, ex) -> {
if(firstSucceedFuture.isDone()) return;
// No job result. returns an error.
System.out.println("No job succeeded. @T:" + Thread.currentThread().getName());
firstSucceedFuture.completeExceptionally(new Exception("Failed"));
});
System.out.println("Wait for fastest job result... @T:" + Thread.currentThread().getName());
System.out.println("First job finished is: " + firstSucceedFuture.get());
System.out.println("Cancel other jobs... @T:" + Thread.currentThread().getName());
allCompletedFuture.cancel(true);
/*
Output result example:
Created job 0 Sleep 9966 @T:ForkJoinPool.commonPool-worker-3
Created job 2 Sleep 7072 @T:ForkJoinPool.commonPool-worker-7
Created job 1 Sleep 6026 @T:ForkJoinPool.commonPool-worker-5
Wait for fastest job result... @T:main
First job finished is: 1
Cancel other jobs... @T:main
*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment