Skip to content

Instantly share code, notes, and snippets.

@mathieucarbou
Created March 7, 2016 17:19
Show Gist options
  • Save mathieucarbou/24ffa755fc2f6f389c1c to your computer and use it in GitHub Desktop.
Save mathieucarbou/24ffa755fc2f6f389c1c to your computer and use it in GitHub Desktop.
Composing multiple futures into one future
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