Репродукция здесь:
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("Hello!");
ExecutorService exec = Executors.newSingleThreadExecutor();
Future<Integer> f = exec.submit(() -> x());
f.get();
System.out.println("f.get() returned");
exec.shutdownNow();
System.out.println("Good bye!");
}
private static Integer x() {
throw new RuntimeException("An unfortunate event");
}
}
Вывод показывает только "Привет!" и исключение трассировки стека, затем программа зависает навсегда.
Изменения, приведенные ниже, обходят проблему, но есть ли идея, почему выполнение зависает в приведенном выше коде?
Использование общего пула потоков НЕ зависает:
Future<Integer> f = ForkJoinPool.commonPool().submit(() -> x());
Завершение вызова вокруг try / catch позволяет приложению нормально завершиться:
Future<Integer> f = exec.submit(() -> x());
try {
f.get();
} catch (Exception ex) {
ex.printStackTrace();
}