Я ищу способ выполнять пакеты задач в java. Идея состоит в том, чтобы иметь ExecutorService
на основе пула потоков, который позволит мне распределять набор Callable
между различными потоками из потока main
. Этот класс должен предоставить метод waitForCompletion , который переводит поток main
в спящий режим до тех пор, пока не будут выполнены все задачи. Затем поток main
должен быть разбужен, и он выполнит некоторые операции и повторно отправит набор задач.
Этот процесс будет повторяться множество раз, поэтому я хотел бы использовать ExecutorService.shutdown
, поскольку для этого потребуется создать несколько экземпляров ExecutorService
.
В настоящее время я реализовал это следующим образом, используя AtomicInteger
и 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();
}
}
Обратите внимание, что я не обязательно буду отправлять все задачи из пакета сразу, поэтому CountDownLatch
не вроде как вариант.
Это правильный способ сделать это? Есть ли более эффективный/элегантный способ реализовать это?
Спасибо