0

わかりました、例を挙げて私が求めていることを説明します。

与えられたときに並列マージアルゴリズムを実装しようとしているとしましょう:

dbは、 db[i]がオブジェクトの ArrayList である配列です。

jはそのサイズです。 Merger(db,cmp,i,j)は、 db[j] db[i] にマージする runnable です

cmp は関連する Comparator です。

これは私が最初に行ったことです:

    ExecutorService e =  Executors.newFixedThreadPool(3);
    while (j>0) 
        for ( i=0;i<j;i++,j--) 
            e.execute(new Merger<E>(db,cmp,i,j));

しかし、最初に完了する必要のある以前のマージがまだ完了していない間に、いくつかのマージが開始されました。(実行中のスレッドがマージが完了する前にループを終了したことは言うまでもありません...)そして、それにより私のプログラムは例外を追い出しました。

これは私ができないことですが、やりたいことなので、あなたの助けが必要です:

    ExecutorService e =  Executors.newFixedThreadPool(3);
    while (j>0) {
        for ( i=0;i<j;i++,j--) 
            e.execute(new Merger<E>(db,cmp,i,j));
        wait for e to announce that all runnables have finished running;
    }

私の意見では、これは機能するはずです。そうでない場合は理由を説明してください。とにかく、どのように行われたか知りたいです。

(基本的に、私は自分のバージョンの FixedThreadPool を実装してそれをヘッペンにすることができますが、私はそうではありません)

4

3 に答える 3

2

あなたは次のものを探しているかもしれませんCountDownLatch:

  • 待機する必要があるスレッドの数を決定し、その数で を作成しCountDownLatchます
  • 構築時にすべてのワーカー スレッドにラッチを渡し、countDown()終了したら呼び出すようにします。
  • ワーカー スレッドをキューに入れるループの後、await()カウントダウンがゼロになること。
于 2012-04-20T16:34:57.887 に答える
1

マージを発行し、それらが完了するのを待つ「startAndRendezvous」ランナブルが必要です。通常、これは、startAndRendezvous 内の CountDownlatch を指すコールバックで設定された一連のマージ実行可能タスクを作成することによって行われます。または、より柔軟に、startAndRendezvous をコンストラクター パラメーターとしてマージ実行可能オブジェクトに渡します。

最新の Java には ForkJoinPool があります。クラスを見てください。明示的なカウントダウン ラッチを使用することで節約できます。

于 2012-04-19T19:12:02.300 に答える
-1

動作する簡単な方法は、Merger で静的カウンターを定義することです。

public class Merger<E> ... {
  public static int runningCount=0;
  public Merger(...){
    runningCount++;
  }
  public void run(){
     ...
     runnningCount--;
  }
}

それで :

ExecutorService e =  Executors.newFixedThreadPool(3);    
while (j>0) {
    for ( i=0;i<j;i++,j--) 
        e.execute(new Merger<E>(db,cmp,i,j));
    while(Merger.runningCount>0)
        Thread.sleep(10);
}
于 2012-04-20T11:41:17.937 に答える