Created
March 7, 2016 17:19
-
-
Save mathieucarbou/24ffa755fc2f6f389c1c to your computer and use it in GitHub Desktop.
Composing multiple futures into one future
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.concurrent.ExecutionException; | |
import java.util.concurrent.Future; | |
import java.util.concurrent.TimeUnit; | |
import java.util.concurrent.TimeoutException; | |
import java.util.function.Function; | |
/** | |
* @author Mathieu Carbou | |
*/ | |
class Futures<T, U> implements Future<U> { | |
private final List<Future<T>> futures; | |
private final Function<? super List<T>, ? extends U> transform; | |
private Futures(List<Future<T>> futures, Function<? super List<T>, ? extends U> transform) { | |
this.futures = futures; | |
this.transform = transform; | |
} | |
@Override | |
public boolean cancel(boolean mayInterruptIfRunning) { | |
boolean canceled = false; | |
for (Future<T> future : futures) { | |
canceled |= future.cancel(mayInterruptIfRunning); | |
} | |
return canceled; | |
} | |
@Override | |
public boolean isCancelled() { | |
boolean canceled = true; | |
for (Future<T> future : futures) { | |
canceled &= future.isCancelled(); | |
} | |
return canceled; | |
} | |
@Override | |
public boolean isDone() { | |
for (Future<T> future : futures) { | |
if (!future.isDone()) { | |
return false; | |
} | |
} | |
return true; | |
} | |
@Override | |
public U get() throws InterruptedException, ExecutionException { | |
List<T> values = new ArrayList<>(futures.size()); | |
for (Future<T> future : futures) { | |
values.add(future.get()); | |
} | |
return transform.apply(values); | |
} | |
@Override | |
public U get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { | |
List<T> values = new ArrayList<>(futures.size()); | |
for (Future<T> future : futures) { | |
values.add(future.get(timeout, unit)); | |
} | |
return transform.apply(values); | |
} | |
public static <T> Future<List<T>> compose(List<Future<T>> futures) { | |
return compose(futures, Function.identity()); | |
} | |
public static <T> Future<Void> composeNoReturn(List<Future<T>> futures) { | |
return compose(futures, ts -> null); | |
} | |
public static <T, U> Future<U> compose(List<Future<T>> futures, Function<? super List<T>, ? extends U> transform) { | |
return new Futures<T, U>(futures, transform); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment