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を超えることはありません。