並行処理(ExecutorService shutdown 後の submit)難易度 高無料
次のコードの実行結果として正しいものを選べ。
1 import java.util.concurrent.*;
2 public class Q9 {
3 public static void main(String[] a) throws Exception {
4 ExecutorService ex = Executors.newSingleThreadExecutor();
5 Future<Integer> f1 = ex.submit(() -> 6 * 7);
6 System.out.println(f1.get());
7 ex.shutdown();
8 Future<Integer> f2 = ex.submit(() -> 1); // 行A
9 System.out.println(f2.get());
10 }
11 }
- A
42を出力後、行A でRejectedExecutionExceptionがスローされる - B
42改行1(shutdown 後も submit は受け付けられる) - Cコンパイルエラー(
submitのRejectedExecutionExceptionを処理していない) - D
42を出力後、行A のsubmitは静かに無視されf2.get()がnullを返す
正解・解説・誤答理由・ひっかけを見る▼ open
✓ 正解:AAI作成・独立検証済
解説
ExecutorService.submit(Callable) はタスクを投入し、結果を Future で受け取る。f1.get() は完了を待って 42 を返す(ここまでは正常)。
問題は7行目の shutdown() 後の8行目。shutdown() は「新規タスクの受け付けを停止」する(既存タスクは完了させるが、新たな submit は拒否する)。
既定の拒否ポリシー(AbortPolicy)により、停止済みエグゼキュータへの submit は実行時に RejectedExecutionException(非検査例外)をスローする。
よって6行目で 42 が出力された後、行A で RejectedExecutionException が投げられ、9行目には到達しない。
RejectedExecutionException は RuntimeException のサブクラスなので、submit のシグネチャに throws は不要(コンパイルは通る)。
- B
shutdown()後は新規タスクを拒否する。行A のsubmitは成功せず例外になる。 - C
RejectedExecutionExceptionは非検査例外(RuntimeException系)なのでthrows/catchは不要。コンパイルは通る。 - D拒否は「無視」ではない。既定ポリシー(
AbortPolicy)は例外を投げるのでf2の取得には到達しない。
ひっかけ:
shutdown() は「今すぐ全部止める」ではなく「新規受付を止め、投入済みは走らせる」。停止後の submit は静かに無視されるのではなく RejectedExecutionException を投げる。即時停止は shutdownNow()(未実行タスクを返す)。実機確認の答え合わせ
出力と例外: 42 Exception in thread "main" java.util.concurrent.RejectedExecutionException: ... (行A の submit で送出。行9 には到達しない)
AIが作成し、独立した検証を経た解説です(有資格者による監修は経ていません)