经测试后发现, execute(Runnable run)日志信息可以正常打印。 submit(callable call)不会打印日志信息。
关键点在改代码 ThreadPoolExcutor类的runWorker()方法(线程池每添加一个线程,就会在worker中添加一个)
final void runWorker(Worker w) {
// ... 省略代码
try {
while (task != null || (task = getTask()) != null) {
// ... 省略代码
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x; // 这里抛出异常
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly); // 抛出异常后,执行这里
}
}
-
execute执行时 task.run()方法,出现异常会直接抛出
-
submit执行时,因为callable类会被转成FutureTask类,FutureTask的run方法中捕获了异常,所以就不会抛出异常。如下
try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { //这里捕获了异常生成了outcome对象 result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { runner = null; int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); }
解决办法手动调用FutureTask的get方法,get方法中会抛出outcome异常 参考