0

我正在使用 ExecutorService 来处理数以千计的小型独立任务。每个任务在完成时都会存储结果(为真或假)。

因此,如果任务找到了答案,我不想处理所有任务,而是过早关闭线程池!感觉就像我在这里遗漏了一些非常明显的东西......

4

2 回答 2

2

考虑使用该invokeAny方法。当只完成一个时它会返回。

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html#invokeAny(java.util.Collection )

于 2011-09-04T14:12:45.530 回答
0

你表达的欲望让我想起了克莱因瓶,里面几乎没有区别什么是“里面”和什么是“外面”。在这里,提交的任务ExecutorService需要知道它们必须在第一次从没有看到真正的任务结果转换到看到至少一个时,通知线程池外的锁存门并关闭它。

我不会为您编写代码,但我会草拟解决方案。定义任务完成时必须调用的接口可能会有所帮助:

interface TaskObserver
{
  void completed(boolean result);
}

每个任务实例都可以通过对这样的 a 的引用来构造,TaskObserver任务主体将在它完成之前调用它并将控制权交还给调用者ExecutorService。你甚至可以编写一个基类来帮助参与这个协议:

public abstract class ObservableTask implements Callable<Boolean>
{
  protected ObservableTask(TaskObserver observer)
  {
    if (null == observer)
      throw NullPointerException();
    observer_ = observer;
  }


  public final Boolean call()
  {
    final boolean result = evaluate();
    observer_.completed(result);
    return result;
  }


  protected abstract boolean evaluate();


  private final TaskObserver observer_;
}

或者,不使用扩展来定义任务,您可以编写一个像这样的具体类,除了引用之外,它在其构造函数中接受对 a的引用,并通过委托来代替。Callable<Boolean>TaskObserver

继续, 的实现TaskObserver将存储一个AtomicBoolean,最初必须设置为 false 。如果传递给的结果为真,则方法主体completed(boolean)必须尝试将from false 设置为 true。如果从 false 到 true 的转换成功,则关闭并停止提交更多任务;对遗嘱的任何后续调用都来自已提交的任务,并且时间太长而无法满足取消请求。AtomicBooleancompleted(boolean)ExecutorServiceTaskObserver

public void complete(boolean result)
{
  if (result &&
      latch_.compareAndSet(false, true))
  {
    // Set a flag to cease submitting new tasks.
    service_.shutdownNow();
    if (!service_.awaitTermination(timeoutMagnitude, timeoutUnit))
    {
      // Report a problem in shutting down the pool in a timely manner.
    }
  }
}

如果这还不足以推动您入门,请跟进其他问题。

于 2011-09-04T15:32:45.570 回答