I was giving my talk on Java Concurrency this morning to a great audience in Denver. Several people knew quite a bit about pre-1.5 Java concurrency, so I was getting interesting questions. As I was demoing ExecutorService and friends, someone asked “But how do I efficiently wait for several Futures?”
Doh! I stop in my tracks. I know there is a simple trick for this, but cannot remember the helper class. Fortunately Brian Goetz is wandering the halls somewhere. Brian is way better than Javadoc, so at the next break he sets me straight (and teases me for not remembering every word of his excellent new book). Here is a little sample showing how you do it:
public class Stump implements Callable {
public final int serialNo;
public Stump(int serialNo) {
this.serialNo = serialNo;
}
public static void main(String[] args) throws Exception {
ExecutorService es = Executors.newCachedThreadPool();
ExecutorCompletionService<Stump> service = new ExecutorCompletionService<Stump>(es);
for (int n=0; n<10; n++)
service.submit(new Stump(n));
for (int n=0; n<10; n++) {
Future<Stump> fs = service.take();
System.out.println("Finished " + fs.get().serialNo);
}
}
public Object call() throws Exception {
Thread.sleep(new Random().nextInt(1000));
return this;
}
}
Comments
public class Stump implements Callable { private int serialNo; /** Create a new stump with given serial number */ public Stump(int serialNo) { this.serialNo = serialNo; } public static void main(String[] args) throws Exception { ExecutorService es = Executors.newCachedThreadPool(); ExecutorCompletionService service = new ExecutorCompletionService(es); // Submit and start each new job for (int n=0; n fs = service.take(); System.out.println("Finished " + fs.get()); } } /** Wait for a random amount of time and return the serial number */ public Integer call() throws InterruptedException { Thread.sleep(new Random().nextInt(10000)); return serialNo; } }public class Stump implements Callable { private int serialNo; public Stump(int serialNo) { this.serialNo = serialNo; } public static void main(String[] args) throws Exception { ExecutorService es = Executors.newCachedThreadPool(); ExecutorCompletionService service = new ExecutorCompletionService(es); for (int n=0; n fs = service.take(); System.out.println("Finished " + fs.get()); } } public Integer call() throws InterruptedException { Thread.sleep(new Random().nextInt(10000)); return serialNo; } }