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