Question 2 is really simple - you are not actually starting a new thread, you are just calling run() , which is executed synchronously in the original thread. You should call start() , after which the exception will not be passed back.
As for exception handling in ScheduledExecutorService - if you call Future.get() , it will throw ExecutionException if the original task throws an exception, throwing the original exception as the reason:
An exception that occurs when you try to get the result of a task that is interrupted by throwing an exception. This exception can be checked using the Throwable.getCause() method.
If you need to answer exceptions without blocking for the future, you can wrap your βrealβ Runnable in another, which is simply delegated to the original run() method, but with the appropriate try / catch block.
source share