2009-08-04 12 views
5

私は、作業を行うメソッドをオーバーライドし、イテレータのような結果を返すクラスを探しています。このような何か:Java並列作業イテレータ?

ParallelWorkIterator<Result> itr = new ParallelWorkIterator<Result>(trials,threads) { 

    public Result work() { 
    //do work here for a single trial... 
    return answer; 
    } 

}; 
while (itr.hasNext()) { 
    Result result = itr.next(); 
    //process result... 
} 

これは主に、モンテカルロシミュレーションのようなもののために使用されようとしているが、私は、スレッド・プールを設定し、帰国のスレッドを毎回の管理に対処する必要がありますする必要はありません。 うまくいけばがこれを成し遂げていると私は自分自身のクラスをロールバックしましたが、私は十分に自信がなく、このようなものが既に存在するかどうかチェックしたいと思っていました。

編集:すべての試行が完了するまで、各作業方法が戻った後、バックグラウンドで実行を継続し、結果を待ち行列に入れておくことを明確にします。したがって、次のメソッドは、キューに結果が返るまで待つことがあります。

答えて

12

ExecutorCompletionServiceをご覧ください。それはあなたが望むすべてを行います。

void solve(Executor e, Collection<Callable<Result>> solvers) 
    throws InterruptedException, ExecutionException { 
     //This class will hold and execute your tasks 
     CompletionService<Result> ecs 
      = new ExecutorCompletionService<Result>(e); 
     //Submit (start) all the tasks asynchronously 
     for (Callable<Result> s : solvers) 
      ecs.submit(s); 
     //Retrieve completed task results and use them 
     int n = solvers.size(); 
     for (int i = 0; i < n; ++i) { 
      Result r = ecs.take().get(); 
      if (r != null) 
       use(r); 
     } 
    } 

CompletionServiceを使用する利点は、常に最初の完了した結果を返すことです。これにより、タスクが完了するのを待たずに、未完了のタスクをバックグラウンドで実行できるようになります。

+0

ありがとうございます、それは私が望むすべてをしているようです。私はちょうどjavaがとても冗長でないことを望む。 – job

+3

冗長で曖昧でないのは、両刃の剣の半分です。 –

+0

私が冗長を処理するために行ったことは、ExecutorCompletionServiceを拡張し、送信されたFutureのリストを保持するラッパークラスを作成することでした。 public boolean hasRemaining(){return 0 Tim

2

Java Executorsを見ることをおすすめします。

多くのタスクをサブミットし、それぞれに対してFutureオブジェクトを取得します。あなたの作品はバックグラウンドで処理され、あなたは上記のようにFutureオブジェクトを反復処理します。それぞれの未来は、利用可能になったときに結果を返します(を呼び出して結果を返します)。

1

もっとも近いことは、CompletionServiceを使用して結果が蓄積されることです。

簡単な例:ExecutionExceptionInterruptedException、そしてあなたは、したがってキャッチし、どちらか飲み込むする必要があります:

ExecutorService executor = Executors.newSingleThreadExecutor(); // Create vanilla executor service. 
CompletionService<Result> completionService = new ExecutorCompletionService<Result>(executor); // Completion service wraps executor and is notified of results as they complete. 
Callable<Result> callable = new MyCallable(); 

executor.submit(callable); // Do not store handle to Future here but rather obtain from CompletionService when we *know* the result is complete. 

Future<Result> fut = completionService.take(); // Will block until a completed result is available. 
Result result = fut.get(); // Will not block as we know this future represents a completed result. 

私は2つの可能なチェック例外をスローすることができますFutureget()方法としてIteratorインタフェースの後ろにこれを包むお勧めしませんこれらは、RuntimeExceptionのようにそれらを投げ直すか、どちらも非常に良いことではありません。さらに、IteratorhasNext()またはnext()メソッドは、進行中のタスクがある場合はブロックする必要があり、Iteratorを使用しているクライアントにとっては直観に反すると見なすことができます。代わりに私は自分のより記述的なインターフェースを実装します。例えば

public interface BlockingResultSet { 
    /** 
    * Returns next result when it is ready, blocking is required. 
    * Returns null if no more results are available. 
    */ 
    Result take() throws InterruptedException, ExecutionException; 
} 

take()と呼ばれる方法が一般的にjava.util.concurrentパッケージにブロッキング呼び出しを表します)。

関連する問題