在項目中使用線程池時,使用瞭如下方式:
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;
}
}