1

タスクを分散するプログラムを作っています。次のようなコミュニケーターオブジェクトの配列リストがあります。

ArrayList<Workers>

ファイルを固定サイズのチャンクに分割し、さまざまなワーカーにディスパッチして、ファイルを処理しています。イテレータを使用して、チャンクをワーカーに均等に渡しています。通常、ワーカーよりも多くのチャンクがあるため、ワーカーの周りをループする必要があります。これを行うにはどうすればよいですか。現在のソリューションでは、イテレータを使用しています。

    private Worker getNextWorker() {
    if (workerIterator == null)
        workerIterator = workers.iterator();

    if (!workerIterator.hasNext())
        workerIterator = workers.iterator();

    return workerIterator.next();
}

メソッドを同期し、メソッドが配列リストを変更しますが、別のスレッドが入ってイテレータ呼び出しの間にコレクションを変更する可能性があるため、これは安全ではありません。したがって、ファイル分割プロセス全体を同期して、1 つの大きなアトミック ステートメントにしました。

1) 何か見逃したことはありますか?

2)この機能をループすることができる別の、おそらくより良い方法はありますか。

4

2 に答える 2

2

車輪の再発明をしないで、そのような目的BlockingQueueで組み合わせて使用​​することをお勧めします。ThreadPoolExecutor

于 2013-03-18T22:46:52.673 に答える
1

ワーカー スレッドを (エグゼキューターなしで) 開始takeし、制限付きブロッキング キューから要素を取得できます。ファイルを読み取っている間put、キューにチャンクします。putキューがいっぱいになると、ワーカーがキューから 1 つのタスクを取得するまでの呼び出しがブロックされます。キューが空の場合、ワーカーはタスクがキューに入れられるまで待機します。処理が完了したらinterrupt、ワーカー スレッドを実行できます。

ThreadPoolExecutorまたは、制限付きブロッキング キューとを使用することもできますCallerRunsPolicy。このようにして、キューがいっぱいでない場合、タスクは実行のために送信されます。キューがいっぱいの場合、呼び出し元のスレッドがタスクを実行します (これにより、ワーカーが処理する時間が与えられます)。このアプローチでは、多くてもnumber_of_threads+queue_capacityチャンクしかありませんが、メイン スレッドの処理中に一部のワーカー スレッドがアイドル状態になる場合があります。

于 2013-03-18T23:30:40.273 に答える