=== execute(): uncaught exception reaches the default handler, gets printed === Exception in thread "pool-1-thread-1" java.lang.RuntimeException: boom from execute() at com.ankurm.executors.LostExceptionTrapDemo.lambda$main$0(LostExceptionTrapDemo.java:22) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614) at java.base/java.lang.Thread.run(Thread.java:1474) === submit(): same exception, but nobody calls get() - dead silence === main: task's Future exists (isDone=true), but its exception was never printed anywhere - it's just sitting inside the Future === submit() + get(): the SAME exception, now surfaced by calling get() === main: caught ExecutionException, cause = java.lang.RuntimeException: boom from submit(), retrieved via get() done