1

i use executor service to launch multiple thread to sent request to api and get data back. sometimes i see some threads haven't finished their job yet, the service kill that thread already, how can i force the service to wait until the thread finish their job?

here is my code:

        ExecutorService pool = Executors.newFixedThreadPool(10);
        List<Future<List<Book>>> futures = Lists.newArrayList();
        final ObjectMapper mapper1 = new ObjectMapper();
        for (final Author a : authors) {
            futures.add(pool.submit(new Callable<List<Book>>() {
                @Override
                public List<Book> call() throws Exception {
                    String urlStr = "http://localhost/api/book?limit=5000&authorId=" + a.getId();

                    List<JsonBook> Jsbooks = mapper1.readValue(
                            new URL(urlStr), BOOK_LIST_TYPE_REFERENCE);

                    List<Book> books = Lists.newArrayList();
                    for (JsonBook jsonBook : Jsbooks) {
                        books.add(jsonBook.toAvro());
                    }

                    return books;
                }
            }));
        }
        pool.shutdown();
        pool.awaitTermination(3, TimeUnit.MINUTES);

      List<Book> bookList = Lists.newArrayList();
    for (Future<List<Book>> future : futures) {
        if (!future.isDone()) {
           LogUtil.info("future " + future.toString());  <-- future not finished yet 
           throw new RuntimeException("Future to retrieve books: " + future + " did not complete");

}
        bookList.addAll(future.get());
    }

and i saw some excepitons at the (!future.isDone()) block. how can i make sure every future is done when executor service shutdown?

user468587
  • 4,799
  • 24
  • 67
  • 124
  • possible duplicate of [How to wait for all threads to finish, using ExecutorService?](http://stackoverflow.com/questions/1250643/how-to-wait-for-all-threads-to-finish-using-executorservice) – Ray May 21 '14 at 19:48
  • What are the exceptions? Seems like the `Future`s are completing, but with an exception in the api call. – tariksbl May 22 '14 at 16:06

1 Answers1

0

I like to use the countdown latch.

Set the latch to the size that you're iterating and pass that latch into your callables, then in your run / call method have a try/finally block that decrements the countdown latch.

After everything has been enqueued to your executor service, just call your latch's await method, which will block until it's all done. At that time all your callables will be finished, and you can properly shut down your executor service.

This link has an example of how to set it up. http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html

Jeff C.
  • 91
  • 4