I have a utility class that contains these:
@FunctionalInterface public interface CheckedSupplier<X> { X get() throws Throwable; } public static <X> Supplier<X> uncheckedSupplier(final CheckedSupplier<X> supplier) { return () -> { try { return supplier.get(); } catch (final Throwable checkedException) { throw new IllegalStateException(checkedException); } }; }
Once you do this using static imports, you can just wait for all futures, like this:
futures.stream().forEach(future -> uncheckedSupplier(future::get).get());
You can also collect all of their results, like this:
List<MyResultType> results = futures.stream() .map(future -> uncheckedSupplier(future::get).get()) .collect(Collectors.toList());
Just reviewing my old post and notice that you had one more grief:
But the problem here is that if, for example, the 4th future throws an exception, then I will unnecessarily wait for the first 3 futures to be available.
In this case, a simple solution is to do this in parallel:
futures.stream().parallel() .forEach(future -> uncheckedSupplier(future::get).get());
Thus, the first exception, although it does not stop the future, will break the forEach statement, as in the sequential example, but since everyone expects in parallel, you do not have to wait for the completion of the first 3.
Brixomatic Jan 08 '19 at 18:49 2019-01-08 18:49
source share