Java提交到线程池(ExecutorService)中的代码出现异常了怎么操作
先看看execute到线程池的问题
public static ThreadFactory spring() {
return new CustomizableThreadFactory("spring-prefix-");
}
/**
* 创建只有1个线程的线程池
*/
public static ExecutorService create(ThreadFactory threadFactory){
return new ThreadPoolExecutor(1, 1, 30, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(30),
threadFactory,
new ThreadPoolExecutor.AbortPolicy());
}
/**
* 提交20个任务, 每5次抛个异常
*/
public static void testExecute(ThreadFactory threadFactory){
ExecutorService service = create(threadFactory);
IntStream.rangeClosed(1,20).forEach(i-> service.execute(()->{
if (i%5==0) {
throw new RuntimeException("error");
}
log.info("done:{}",i);
}));
}
public static void main(String[] args) {
testExecute();
}
运行看日志
发现问题了没?
- 每次抛出异常就会创建一个新的线程,线程池本身是让线程重复利用,结果倒好,每次创建一个新的。
- 再有就是抛出的异常都不知道咋来的
解决办法?
- 执行的代码加上try-catch处理
- 加上线程异常处理
- 可以自定义
ThreadFactory
咋定义? 看我之前的文章 - 也可以定义全局线程异常处理
- 可以自定义
static {
Thread.setDefaultUncaughtExceptionHandler((thread, throwable)-> log.error("Thread {} got exception", thread, throwable));
}
再看看submit到线程池的问题
public static void testSubmit(){
ExecutorService service = create(spring());
List<? extends Future<?>> error = IntStream.rangeClosed(1, 20).mapToObj(i -> service.submit(() -> {
if (i % 5 == 0) {
throw new RuntimeException("error");
}
log.info("done:{}", i);
})).collect(Collectors.toList());
}
查看日志
异常被生吞了。
解决办法
public static void testSubmit(){
ExecutorService service = create(spring());
List<? extends Future<?>> error = IntStream.rangeClosed(1, 20).mapToObj(i -> service.submit(() -> {
if (i % 5 == 0) {
throw new RuntimeException("error");
}
log.info("done:{}", i);
})).collect(Collectors.toList());
// 得到future后get操作处理异常
error.forEach(task->{
try {
task.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
得到future后get操作处理异常