在项目中使用线程池时,使用了如下方式:
ExecutorService dataUploadPool = Executors.newFixedThreadPool(writeThreadNum);
dataUploadPool.execute(new Thread(task))
但是这种方式下,主线程无法捕获子线程中的异常,也就无法在子线程出现异常时采取措施。
如果换一个实现方式就可以捕获子线程异常,步骤如下:
1. 以submit方式提交执行并返回Future对象
2. 执行Futrue的get方法获取执行结果
3. 捕获get方法抛出的执行异常
final ExecutorService dataUploadPool = Executors.newFixedThreadPool(writeThreadNum);
List<Future> results = new ArrayList<>();
for (File f : file.listFiles()) {
if (f.isDirectory()) {
....
results.add(dataUploadPool.submit(dataDao));
}
}
}
// 关闭线程池
dataUploadPool.shutdown();
// 检查线程池中线程是否抛出异常,若异常则退出执行
for (Future task : results) {
try {
task.get();
} catch (Exception e) {
logger.error(e.getMessage(), e);
return;
}
}
dataDao需要实现Callable接口并实现call方法:
public abstract class AbstractDao implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
loadDataFromFileToDB();
return true;
}
}