Javaでのマルチスレッド処理ではThreadPoolExecutorが便利.
ExecutorServiceを使ってスレッドプールを作る以下のようなコードが良く利用される.
ExecutorService exec = Executors.newFixedThreadPool(3);
ただし,ExecutorServiceでは固定スレッド数のスレッドプールを作っても
最大コア数は制限されていないようで,スレッド数に余裕があり,
多数のタスクがexecuteもしくはsubmitされるとスレッド数が指定値以上になってしまう.
そこでThreadPoolExecutorクラスでThreadPoolを作っておき,最大コア数を指定しておく.
この状態で順次Runnableクラスをsubmitすると固定スレッド数で実行できる.
終了検知はawaitTerminationでもよいが,各タスクがきちんと終了したか確認するには,
submitの返り値のfutureを使いfuture.get()で待機する方法もある.
(2021/1/19 内容に誤りがありましたので,記事タイトルと説明を修正しました.)