在以下方案中,我的任务会抛出异常。我不同意,在一次请求之后,我的池将无法处理任何进一步的请求,但它没有发生。线程池在这种情况下的行为如何?如何从池线程到主应用程序线程发生异常通信?
public class CallableClass implements Callable<String> {
@Override
public String call() throws Exception {
throw new RuntimeException();
}
}
class Test {
ExecutorService executor = Executors.newFixedThreadPool(1);
public void execute(){
try {
System.out.println(executor);
Future<String> future = executor.submit(new Task());
System.out.println(executor);
future.get();
}catch(Exception e) {
System.out.println(executor);
e.printStackTrace();
}
}
}
答案 0 :(得分:1)
您可以通过打印当前正在执行的线程的名称来检查它:
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName());
...
}
- 线程池在这种情况下的行为如何?
醇>
工作人员通知执行程序服务它在工作时发生的异常。但是没有理由从ThreadPoolExecutor#workers
集中移除该工作者。如果有需要,它将继续工作。
您不应该看到执行程序服务的任何失败。如果发生错误,它会用有效的工作者(或线程)替换无效的工作者(或线程):
如果任何线程因关闭前执行期间的故障而终止,则在需要执行后续任务时,新的线程将取代它。
- 如何从池线程到主应用程序线程发生异常通信?
醇>
Callable#call
引发的任何异常都被ExecutionException
包裹并弹出到调用方:
@throws
ExecutionException
如果计算引发异常Future.get() [JDK 9]
支持ExecutionException#getCause
是RuntimeException
实例的一个示例:
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause != null && cause instanceof RuntimeException) {
System.out.println("A RuntimeException was thrown.");
}
}