Picture of admin

Java Concurrency Stump the Chump

  • Posted By admin on November 12, 2005

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
  1. Gary BlomquistNovember 15, 2005 @ 02:50 PM
    The code doesn't compile. You didn't specify the type to ExecutorCompletionService and Future does not have a serialNo member.
  2. Stuart HallowayNovember 15, 2005 @ 03:04 PM
    Hmm... The code compiles and runs fine locally, but my blog software erroneously failed to escape the < for the generic <Stump. In fact, it appears to have done something totally weird, turing <Stump> into the tag pair <stump></stump>, with the close tag in weird random places later in the document. Guess blogs and Java generics are incompatible. :-)
  3. Brett RyanNovember 21, 2005 @ 12:21 AM
    Hi there, not too far off on a good example, though there are a few things. 1). You shouldn't be escaping your "Finished" string (\"). 2). You might want to return serialNo directly from your call method since this is all you are using. 3). You forgot the shutdown() statement for the ExecutorService You could write this similar to the following: 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; } }
  4. Brett RyanNovember 21, 2005 @ 12:24 AM
    Oh my, looks like the comments prevented code blocks, here hope this one looks okay, my appologies if it doesn't. 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; } }
  5. Stuart HallowayNovember 23, 2005 @ 11:45 AM
    Good points, Brett -- if anyone is pasting code from this blog entry they should use Brett's version. WRT to the incorrectly escaped strings: you can thank MarsEdit for that! My workflow is "Write code. Test that code works. Paste code into MarsEdit. MarsEdit does random violence..." :-)
  6. Modern ChaiseApril 29, 2006 @ 06:18 PM
    That's awesome :(
  7. I thout to do it in my local version :(
  8. Cell Phone Razor RecallMay 02, 2006 @ 06:20 PM
    i am not sure as to why :(
  9. Farberware Tea KettleMay 03, 2006 @ 07:32 AM
    The problem is my browser.
  10. Baccarat Quartz DecanterMay 05, 2006 @ 10:58 AM
    Gonna have to give it a try.
  11. Total Management FinancialMay 10, 2006 @ 06:49 PM
    Thanks for the write-up :(
  12. Caesar Julius Shakespeare WilliamMay 10, 2006 @ 08:36 PM
    I use Firefox in Ubuntu!
  13. Archive Erotic NiftyMay 12, 2006 @ 11:10 AM
    Very nice write up :)
  14. Arouse And The City QuoteMay 12, 2006 @ 11:10 AM
    The problem is my browser...
  15. Background Check ServiceMay 14, 2006 @ 02:12 AM
    Thanks.