Java(java.util.concurrent)でスレッドプールを実装する必要があります。スレッドプールの数は、アイドル時に最小限の値になり、上限に達しますさらに)ジョブが実行を完了するより速くそれに投入され、すべてのジョブが完了し、それ以上ジョブがサブミットされないときに下限に縮小されます。動的(拡大/縮小)スレッドプールの作成
どのようにそのようなものを実装しますか?私はこれがかなり一般的な使用シナリオであると思いますが、明らかに多くのジョブが送信されたときに固定サイズのプールとプールを作成できるのは、java.util.concurrent.Executors
のファクトリメソッドだけです。 ThreadPoolExecutor
クラスはcorePoolSize
とmaximumPoolSize
のパラメータを提供しますが、そのドキュメントはcorePoolSize
スレッド以上を同時に持つ唯一の方法は境界ジョブキューを使用することを暗示しているようですが、maximumPoolSize
スレッドに達した場合は、あなたはあなた自身に対処しなければならない雇用拒否を得るでしょうか?私はこれを思いついた:
//pool creation
ExecutorService pool = new ThreadPoolExecutor(minSize, maxSize, 500, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(minSize));
...
//submitting jobs
for (Runnable job : ...) {
while (true) {
try {
pool.submit(job);
System.out.println("Job " + job + ": submitted");
break;
} catch (RejectedExecutionException e) {
// maxSize jobs executing concurrently atm.; re-submit new job after short wait
System.out.println("Job " + job + ": rejected...");
try {
Thread.sleep(300);
} catch (InterruptedException e1) {
}
}
}
}
私は何か見落としていますか?これを行うより良い方法はありますか?また、要件に応じて、上記のコードが少なくとも完了するまで問題が生じる可能性があります。(total number of jobs) - maxSize
ジョブが終了しました。だから、あなたがプールに任意の数のジョブを提出し、それらのいずれかが終了するのを待たずにすぐに進むことができるようにしたいのであれば、私はそれをどうやって行うことができるのか分かりません。発行されたすべてのジョブを保持するために必要な無制限のキューAFAICSでは、ThreadPoolExecutor自体に無制限のキューを使用している場合、そのスレッド数はcorePoolSizeを超えて増加することはありません。
私は、動的サイズのスレッドプールの有用性を見ることはできません。アプリケーションの稼働時間中にボード上のプロセッサ数が変化しますか? – corsiKa
'newCachedThreadPool'があなたの状況に適していないのはなぜですか?もはや使用されなくなったスレッドを自動的に無効にします。 – Tudor
あなたのアイドルスレッドが死んでいない場合はどうなりますか?常に最大サイズの固定サイズのプールを持っていたとしますか?何が起こるのだろうか? –