可変数のスレッドを作成する必要があるたびに。これを行うには、スレッドの配列を作成し、複数のスレッドを作成します。
しかし、マルチスレッドの概念のように動作するこれらの n 個のスレッドを開始する方法がわかりません。それらを並行して実行したい。
このシナリオで何をすべきかを教えてください。
可変数のスレッドを作成する必要があるたびに。これを行うには、スレッドの配列を作成し、複数のスレッドを作成します。
しかし、マルチスレッドの概念のように動作するこれらの n 個のスレッドを開始する方法がわかりません。それらを並行して実行したい。
このシナリオで何をすべきかを教えてください。
しかし、マルチスレッドの概念のように動作するこれらのn個のスレッドを開始する方法がわかりません。それらを並行して実行してほしい。
確かに、ループを使用してスレッドの配列を作成できます。
Thread[] threads = new Thread[NUM_JOBS_TO_CREATE];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
// some code to run in parallel
// this could also be another class that implements Runnable
}
});
threads[i].start();
}
これにより、スレッドがバックグラウンドで並行して実行されます。その後、後で参加して、すべてが完了するのを待ってから続行できます。
// wait for the threads running in the background to finish
for (Thread thread : threads) {
thread.join();
}
ただし、スレッドを自分で管理する代わりに、組み込みのJavaExecutors
を使用することをお勧めします。彼らはあなたのためにこれらすべてを行い、管理がより簡単になります。この方法の利点の1つは、タスクを実行するスレッドからタスクを分離することです。たとえば、10個のスレッドを開始して、1000個と1000個のタスクを並行して実行できます。
サンプルExecutorService
コードは次のとおりです。
// create a pool of threads, 10 max jobs will execute in parallel
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// submit jobs to be executing by the pool
for (int i = 0; i < NUM_JOBS_TO_CREATE; i++) {
threadPool.submit(new Runnable() {
public void run() {
// some code to run in parallel
// this could also be another class that implements Runnable
}
});
}
// once you've submitted your last job to the service it should be shut down
threadPool.shutdown();
// wait for the threads to finish if necessary
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
詳細については、スレッドエグゼキュータに関するJavaチュートリアルを参照してください。
スレッドの配列を作成せず、それらを管理しようとするのは非常に難しいことです。すぐにひどい混乱に陥ります。タスクを実行するためにスレッドのプールが必要な場合は、プロデューサー/コンシューマー キューが必要です。1 つ作成し、それ (またはそれをメンバとして含むスレッドプール オブジェクト インスタンス) をスレッドの作成時にスレッドに渡します。スレッドはループを繰り返し、タスクを取得して実行します。
これを行う簡単な方法は、@Gray (+1) で詳述されている ExecutorService を使用することです。
繰り返しになりますが、スレッドを配列、リスト、またはベクトルで細かく管理したり、開始したり、「ボス/管理」ループでスレッドの状態を確認したり、終了/中止したり、破棄したりしないでください。ポルシェ 911 のように - 莫大な金額と時間を費やして入手した後、正常に動作しているように見えたものが突然壊れて、あなたを木に巻き上げます。
長時間ブロックするジョブには専用スレッドを使用し、集中的かつ迅速に実行できるジョブにはスレッドプールを使用します。
基本的な擬似コード:
create x threads, store them in an array or list;
for each thread in the list/array
call start() on the thread object;
マルチスレッド化が必要なクラスでは、クラスの先頭に次のように設定しました。
private static final ExecutorService executor = Executors.newCachedThreadPool();
& Java 8+では、新しいスレッドで何かを実行する必要がある場合はいつでもラムダ式を使用します:
executor.submit(() -> {
myOtherClass.myFunction(doSomething);
});
Java を使用newCachedThreadPool
すると、システム上の CPU コアの数に応じてスレッドの総数を管理し、非アクティブな期間 (60
デフォルトでは秒) 後に自動的に停止します。