you can use CompletionService. The results of the callables are put in a queue, and you can take the results of the tasks as soon as they complete.
in this case, you don't need to wait for the results of Foo if Bar completes earlier.
for example:
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CompletionServiceExample {
private static Logger LOGGER = Logger.getLogger("CompletionServiceExample");
public static void main(String[] args) throws InterruptedException {
CompletionServiceExample completionServiceExample = new CompletionServiceExample();
completionServiceExample.doTheWork();
}
private void doTheWork() throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
final CompletionService<Boolean> completionService = new ExecutorCompletionService<>(executorService);
completionService.submit(new Foo());
completionService.submit(new Bar());
int total_tasks = 2;
for(int i = 0; i < total_tasks; ++i) {
try {
final Future<Boolean> value = completionService.take();
System.out.println("received value: " + value.get());
} catch (ExecutionException e) {
LOGGER.log(Level.WARNING, "Error while processing task. ", e);
} catch (InterruptedException e) {
LOGGER.log(Level.WARNING, "interrupted while waiting for result", e);
}
}
executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);
}
}
class Foo implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
Thread.sleep(5000);
return true;
}
}
class Bar implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
Thread.sleep(1000);
return false;
}
}