Suppose you need to submit a set of background tasks, and you want to wait for each one to become available and process its result, but you don't want to block waiting for all of them before you start processing. You can use an ExecutorCompletionService.
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public final class Main {
public static void main(String[] args) throws Exception {
// Bootstrap CompletionService backed by a pool of 5 daemon threads.
CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(
Executors.newFixedThreadPool(5, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}));
// Submit 20 contrived Callables that just return a monotonically
// increasing integer. Introduce a random sleep just to make the
// multi-threading effects more visible.
int n = 20;
for (int i = 0; i < n; ++i) {
final Integer result = i;
// The submit call does not block here.
cs.submit(new Callable<Integer>() {
@Override
public Integer call() {
try {
Thread.sleep((long)(Math.random() * 10));
return result;
} catch (InterruptedException e) {
return null;
}
}
});
}
for (int i = 0; i < n; ++i) {
// The take call blocks here until the next Callable finishes.
Integer result = cs.take().get();
if (result != null) {
System.out.println(result);
}
}
}
}