Combining via anyOf()

Let's assume that we want to organize a raffle for our customers:

List<String> customers = Arrays.asList(
"#1", "#4", "#2", "#7", "#6", "#5"
);

We can start to solve this problem by defining the following trivial method:

public static CompletableFuture<String> raffle(String customerId) {

return CompletableFuture.supplyAsync(() -> {
Thread.sleep(new Random().nextInt(5000));

return customerId;
});
}

Now, we can create an array of CompletableFuture<String> instances, as follows:

CompletableFuture<String>[] cfCustomers = customers.stream()
.map(CustomerAsyncs::raffle)
.toArray(CompletableFuture[]::new);

To find the winner of the raffle, we want to run cfCustomers in parallel, and the first CompletableFuture that completes is the winner. Since the raffle() method blocks for a random number of seconds, the winner will be randomly chosen. We are not interested in the rest of the CompletableFuture instances, so they should be completed immediately after the winner has been chosen.

This is a job for anyOf​(CompletableFuture<?>... cfs). It returns a new CompletableFuture that is completed when any of the involved CompletableFuture instances completes. Let's see it at work:

CompletableFuture<Object> cfWinner 
= CompletableFuture.anyOf(cfCustomers);

Object winner = cfWinner.get();

// e.g., Winner: #2
logger.info(() -> "Winner: " + winner);
Pay attention to scenarios that rely on CompletableFuture that return results of different types. Since anyOf() returns CompletableFuture<Object>, it is difficult to know the CompletableFuture types that have completed first.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.131.38.14