2. Executor Service フレームワーク (16-30)
Java Gold試験において、ExecutorServiceは「スレッドを手動で管理する(Threadクラスを使う)」時代から、「タスクを投げて管理を任せる」時代への進化を象徴する重要な分野です。
16番から30番まで、全項目をサンプルコードと共に徹底解説します。
16-19. ExecutorServiceの生成¶
スレッドの作り方をExecutor(実行者)に任せます。
Java
// 16. ExecutorService: インターフェース。実装はExecutorsユーティリティから取得
// 17. SingleThreadExecutor: 1つのスレッドでタスクを順次実行
ExecutorService single = Executors.newSingleThreadExecutor();
// 18. FixedThreadPool: 指定した数のスレッドを使い回す
ExecutorService fixed = Executors.newFixedThreadPool(3);
// 19. CachedThreadPool: 必要に応じてスレッドを増やす(暇になると破棄)
ExecutorService cached = Executors.newCachedThreadPool();
20-21. タスクの実行 (execute vs submit)¶
試験で最も問われる戻り値の違いです。
Java
// 20. execute(Runnable): 戻り値なし(void)。「投げっぱなし」
fixed.execute(() -> System.out.println("Runnable task"));
// 21. submit(Callable/Runnable): 結果を受け取るためのFutureを返す
Future<Integer> future = fixed.submit(() -> {
Thread.sleep(1000);
return 100;
});
22-25. 終了処理 (Shutdown)¶
Executorは使い終わったら必ず終了させる必要があります。
Java
// 22. shutdown(): 新規受付停止。現在実行中・待機中のタスクは最後までやる
fixed.shutdown();
// 23. shutdownNow(): 実行中のタスクを中断(interrupt)し、待機中タスクのリストを返す
// List<Runnable> droppedTasks = fixed.shutdownNow();
// 24. isShutdown() vs isTerminated()
// isShutdown: shutdownが呼ばれたか
// isTerminated: 全タスクが完全に終了したか
System.out.println(fixed.isTerminated());
// 25. awaitTermination: 全終了まで最大で指定時間待つ
if (fixed.awaitTermination(5, TimeUnit.SECONDS)) {
System.out.println("All finished");
}
26-28. Futureインターフェース¶
submit() の結果をどう扱うかです。
Java
// 26. Future.get(): 結果が出るまで呼び出し側スレッドをブロック(待機)
try {
Integer result = future.get(); // 完了するまでここで待つ
} catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
// 27. isDone(): タスクが(完了/例外/キャンセルで)終わったか確認
if (future.isDone()) { System.out.println("Done!"); }
// 28. cancel(boolean): タスクをキャンセル
// 引数trueなら、実行中の場合に割り込み(interrupt)をかける
future.cancel(true);
29-30. 複数タスクの一括実行¶
試験では「全部待つのか、一つでいいのか」の違いが出ます。
Java
List<Callable<String>> tasks = List.of(
() -> "Task 1",
() -> "Task 2"
);
// 29. invokeAll: 全てのタスクが完了するまで待ち、Futureのリストを返す
List<Future<String>> futures = fixed.invokeAll(tasks);
// 30. invokeAny: どれか1つが成功するまで待ち、その結果(T型)を直接返す
// 他の実行中のタスクはキャンセルされる
String firstResult = fixed.invokeAny(tasks);
💡 Java Gold 試験対策の「ひっかけ」チェック¶
- Future.get() の例外:
future.get()はInterruptedExceptionだけでなく、タスク内で起きた例外を包むExecutionExceptionも投げます。 - shutdown() を忘れると?:
ExecutorServiceは非デーモンスレッドを持つため、shutdown()を呼ばないとプログラムが終了しません。 - submit(Runnable) の戻り値:
submit(Runnable)を呼んだ場合、Future<?>が返りますが、そのget()の戻り値は常にnullです。 - invokeAny の戻り値:
invokeAllはList<Future>を返しますが、invokeAnyは 結果そのもの(T型) を返します。
次は、時間指定で実行する 「31-40. Scheduled Executor Service」 に進みますか?それともこの範囲の練習問題を出しましょうか?