Как реализовать ExecutorService для выполнения пакетов задач

Я ищу способ выполнять пакеты задач в 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не вроде как вариант.

Это правильный способ сделать это? Есть ли более эффективный/элегантный способ реализовать это?

Спасибо

5
задан Victor P. 24 April 2012 в 12:46
поделиться