2

実行時間が変化するタスクを含むマルチスレッド アプリケーションに取り組んでいます。1 つのスレッドが終了したときに、まだ実行中のスレッドからいくつかのタスクを引き継ぐ方法はありますか?

ここに例があります。私は 5 つのスレッドでプログラムを開始し、それぞれに 50 のタスクがあります。最も速く実行されているスレッドが終了しても、別のスレッドにはまだ 40 個のタスクが残っています。実行中のスレッドが残りの 40 を完了するのを待つのではなく、終了したスレッドが他のスレッドから 20 個のタスクを取得して、それぞれが 20 個の作業を続行できるようにするにはどうすればよいですか?

4

4 に答える 4

4

を使用することをお勧めしますThreadPoolExecutor。空きスレッドにタスクを自動的に割り当てます。

于 2016-01-05T14:30:37.530 に答える
3

Executorsクラスのおかげで作成されたスレッド プールを使用します。

 ExecutorService es = Executors.newFixedThreadPool(5);
 List<Runnable> tasks = // create your 50 runnable
 List<Future<?>> futures = new ArrayList<>(tasks.size());
 for(Runnable r : tasks) {
     Future<?> f = es.submit(t);
     futures.add(f);
 }

ドキュメンテーションは、それがどのように機能するかを非常によく説明しているので、見てみることをお勧めします。

于 2016-01-05T14:35:09.327 に答える
3

ForkJoinPoolを使用する

ForkJoinPool が他の種類の ExecutorService と異なるのは、主にワーク スティーリングを採用している点です。プール内のすべてのスレッドは、他のアクティブなタスクによって作成されたサブタスクを見つけて実行しようとします (存在しない場合は、最終的にワークの待機をブロックします)。これにより、ほとんどのタスクが他のサブタスクを生成するときに効率的な処理が可能になります (ほとんどの ForkJoinTask がそうであるように)。コンストラクターで asyncMode を true に設定する場合、ForkJoinPools は、決して結合されないイベント スタイルのタスクでの使用にも適している場合があります。

Java 8 は Executor でもう 1 つの API を提供します

static ExecutorService  newWorkStealingPool()

使用可能なすべてのプロセッサをターゲット並列処理レベルとして使用して、ワークスティーリング スレッド プールを作成します。

ForkJoinPool タスク盗用

詳細については、このigvtia の記事Ilya Grigorik ご覧ください。

などの他の関連する Java 並行 API @チュートリアルをご覧ください。ThreadPoolExecutorExecutorService

于 2016-01-05T14:38:33.613 に答える