submit 是无法自动打印异常,因为它将 run 方法抛出的异常捕获后封装到了 Future 的 get 方法上
在主线程中调用 Future.get 就能捕获到 run 方法中抛出的异常
- Future.get 会阻塞调用者的线程,直到通过 submit 提交的任务的 run 方法执行结束之后才会放开调用 Future.get 的线程。这也就是说,Future.get 将两个并行执行的线程变成了顺序执行。所以与其说线程池是将 run 方法抛出的异常捕获并封装到了 Future 的 get 方法上。倒不如说是调用了 Future.get 之后,调用者线程就一直在等待 run 方法执行完毕,如果 run 方法抛出了异常,就经由 Future.get 方法传递给调用者。
- 如果不调用 Future.get 的话,run 方法抛出的异常就像被线程池吃掉了一样,有时候会让你摸不着头脑。明明 run方法抛出异常了,而你的控制台却没有任何异常打印,原因就出在了这里。
public interface Future<V> {
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
* @throws TimeoutException if the wait timed out
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;