How to implement an ExecutorService to execute batches of tasks
executorservice, java, multithreading
Solution
I think the ExecutorService itself will be able to perform your requirements.
Call `invokeAll([...])` and iterate over all of your Tasks. All Tasks are finished, if you can iterate through all Futures.
Problem
I am looking for a way to execute batches of tasks in java. The idea is to have an `ExecutorService` based on a thread pool that will allow me to spread a set of `Callable` among different threads from a `main` thread. This class should provide a waitForCompletion method that will put the `main` thread to sleep until all tasks are executed. Then the `main` thread should be awaken, and it will perform some operations and resubmit a set of tasks. This process will be repeated numerous times, so I would like to use `ExecutorService.shutdown` as this would require to create multiple instances of `ExecutorService`. Currently I have implemented it in the following way using a `AtomicInteger`, and a `Lock`/`Condition`: ``` public class BatchThreadPoolExecutor extends ThreadPoolExecutor { private final AtomicInteger mActiveCount; private final Lock mLock; private final Condition mCondition; public <C extends Callable<V>, V> Map<C, Future<V>> submitBatch(Collection<C> batch){ ... for(C task : batch){ submit(task); mActiveCount.incrementAndGet(); } } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); mLock.lock(); if (mActiveCount.decrementAndGet() == 0) { mCondition.signalAll(); } mLock.unlock(); } public void awaitBatchCompletion() throws InterruptedException { ... // Lock and wait until there is no active task mLock.lock(); while (mActiveCount.get() > 0) { try { mCondition.await(); } catch (InterruptedException e) { mLock.unlock(); throw e; } } mLock.unlock(); } } ``` Please not that I will not necessarily submit all the tasks from the batch at once, therefore `CountDownLatch` does not seem to be an option. Is this a valid way to do it? Is there a more efficient/elegant way to implement that? Thanks