How to wait for all threads to finish, using ExecutorService?

前端 未结 26 2585
你的背包
你的背包 2020-11-22 01:55

I need to execute some amount of tasks 4 at a time, something like this:

ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
    tas         


        
26条回答
  •  夕颜
    夕颜 (楼主)
    2020-11-22 02:40

    You can use Lists of Futures, as well:

    List futures = new ArrayList();
    // now add to it:
    futures.add(executorInstance.submit(new Callable() {
      public Void call() throws IOException {
         // do something
        return null;
      }
    }));
    

    then when you want to join on all of them, its essentially the equivalent of joining on each, (with the added benefit that it re-raises exceptions from child threads to the main):

    for(Future f: this.futures) { f.get(); }
    

    Basically the trick is to call .get() on each Future one at a time, instead of infinite looping calling isDone() on (all or each). So you're guaranteed to "move on" through and past this block as soon as the last thread finishes. The caveat is that since the .get() call re-raises exceptions, if one of the threads dies, you would raise from this possibly before the other threads have finished to completion [to avoid this, you could add a catch ExecutionException around the get call]. The other caveat is it keeps a reference to all threads so if they have thread local variables they won't get collected till after you get past this block (though you might be able to get around this, if it became a problem, by removing Future's off the ArrayList). If you wanted to know which Future "finishes first" you could use some something like https://stackoverflow.com/a/31885029/32453

提交回复
热议问题