Java 线程池优化:高效更新本地 JSON 文件
该代码片段展示了如何使用 Java 线程池优化更新本地 JSON 文件的操作。代码的核心逻辑是循环遍历 allMapSycTrainMap 中的数据,并使用线程池来异步更新对应的 JSON 文件。
以下是对代码的具体分析和优化建议:
-
线程池优化: 使用
Executors.newFixedThreadPool(2)创建一个固定线程数为 2 的线程池,避免频繁创建和销毁线程带来的性能损耗。 -
同步块: 使用
synchronized块来保证对allMapSycTrainMap的访问是线程安全的。 -
文件操作优化: 使用
try-with-resources语句确保文件流在使用后能够正确关闭,避免资源泄漏。 -
代码逻辑优化: 代码中将文件操作和文件重命名操作分开,并使用线程池来异步执行文件操作,提高了代码的效率。
-
代码可读性优化: 代码中对变量和方法的命名进行了优化,提高了代码的可读性。
以下是优化后的代码:
private void checkIsUploadAndUpdateFile() {
try {
ExecutorService executorService = Executors.newFixedThreadPool(2);
// 1. 循环训练场 allMapSycTrainMap 中数据 - 加锁
synchronized (allMapSycTrainMap) {
for (Map.Entry<Long, MapSycTrain> entry : allMapSycTrainMap.entrySet()) {
Long key = entry.getKey();
MapSycTrain value = entry.getValue();
Thread fileCheckThread = new Thread(() -> {
File folder = new File(mapSycTrainPath); // 本地文件夹路径
File[] files = folder.listFiles();
if (files != null) {
List<Long> ids = new ArrayList<>();
for (File file : files) {
String[] fileName1 = file.getName().split("-");
Long trainingGroundIdByLocal = Long.valueOf(fileName1[0]);// 文件训练场 ID
ids.add(trainingGroundIdByLocal);
}
for (File file : files) {
String[] fileName1 = file.getName().split("-");
String[] fileName2 = fileName1[1].split("\.");
Long trainingGroundIdByLocal = Long.valueOf(fileName1[0]);// 文件训练场 ID
Long timeByLocal = Long.valueOf(fileName2[0]);// 文件时间版本
if (!ids.contains(key)) {
// 把 Detail 数据深拷贝一份,(使用 io 线程写入文件)将内存中的数据(深拷贝的数据)更新到本地 json 文件
List<DetailRouteMapData> detailRouteMapDataList = getDetailRouteMapDataListByTrainingGroundIdOrProjectRouteMapDataId(key);
try {
List<DetailRouteMapData> copiedList = deepCopy(detailRouteMapDataList);// 深拷贝
Map<Long, DetailRouteMapData> map = new HashMap<>();
for (DetailRouteMapData data : copiedList) {
map.put(data.getId(), data);
}
String json = JSON.toJSONString(map);
String filePath = mapSycTrainPath + key + "-" + System.currentTimeMillis() + ".json";
try (FileWriter fileWriter = new FileWriter(filePath)) {
// 将 JSON 对象写入文件
fileWriter.write(json);
fileWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
} else if (Objects.equals(key, trainingGroundIdByLocal) && !Objects.equals(value.time, timeByLocal)) {
// 开启新的线程去操作
Thread fileOperationThread = new Thread(() -> {
// 把 Detail 数据深拷贝一份,(使用 io 线程写入文件)将内存中的数据(深拷贝的数据)更新到本地 json 文件
List<DetailRouteMapData> detailRouteMapDataList = getDetailRouteMapDataListByTrainingGroundIdOrProjectRouteMapDataId(key);
try {
List<DetailRouteMapData> copiedList = deepCopy(detailRouteMapDataList);// 深拷贝
Map<Long, DetailRouteMapData> map = new HashMap<>();
for (DetailRouteMapData data : copiedList) {
map.put(data.getId(), data);
}
String json = JSON.toJSONString(map);
String filePath = mapSycTrainPath + file.getName();
// 使用 try-with-resources 语句确保文件资源正确关闭
try (FileOutputStream fos = new FileOutputStream(filePath, false);
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
BufferedWriter writer = new BufferedWriter(osw)) {
// 清空文件内容
writer.write("");
// 写入 JSON 字符串到文件
writer.write(json);
} catch (IOException e) {
e.printStackTrace();
}
reName(mapSycTrainPath + file.getName(), mapSycTrainPath + key + "-" + value.time + ".json"); // 修改文件名
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
});
executorService.submit(fileOperationThread);
}
}
}
});
executorService.submit(fileCheckThread);
}
}
executorService.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
说明:
- 代码中的
getDetailRouteMapDataListByTrainingGroundIdOrProjectRouteMapDataId和deepCopy方法是示例方法,具体实现需要根据实际情况进行修改。 - 代码中的
mapSycTrainPath是本地文件夹路径,也需要根据实际情况进行修改。 - 代码中使用了
System.currentTimeMillis()生成新的文件名,可以根据实际需求修改文件名生成方式。 - 代码中使用了
reName方法来修改文件名,也需要根据实际情况进行修改。
总结:
通过使用线程池和同步块,以及 try-with-resources 语句,可以提高代码的效率和安全性,并使代码更加易于维护。
注意事项:
- 在使用线程池时,需要根据实际情况设置合适的线程数,避免过多的线程导致系统资源不足。
- 在使用同步块时,要确保同步的代码块尽可能短,避免过长的同步块导致其他线程等待时间过长。
- 在使用文件操作时,要确保文件路径正确,并处理好异常情况。
- 在使用 deepCopy 方法时,需要根据实际情况选择合适的深拷贝方法。
原文地址: http://www.cveoy.top/t/topic/qtT2 著作权归作者所有。请勿转载和采集!