我有ArrayList
。它包含大约20,000个文件路径元素。
private List<Path> listOfPaths = new ArrayList<>();
我想在多线程模式下读取这些路径上的文件内容。
问题是这段代码运行得很慢。如何选择多个线程以便每个线程读取文件并将其写入dto
?如何解决一个线程开始处理文件的问题,以便其他线程不对同一个文件做同样的事情?
答案 0 :(得分:1)
我创建了ioPool,以便不使用io操作阻止公共池(默认情况下在并行流操作中使用)。通常情况下,如果你正在进行io操作,你可以创建dump_only
个线程,但它确实受到其他人提到的限制。
你可以像下面这样做。这不会按顺序处理您的文件列表。
core-count* 2
答案 1 :(得分:1)
您可以将工作分成较小的块,每个线程处理所有文件的一部分。每个线程都有自己的待处理数据子列表和已处理数据列表,以避免尝试同时读取/写入相同数据的任何风险。当所有线程都完成后,你会收集结果。
实际上你可以让java 8并行流为你做分裂/ mergin等的艰苦工作。
使用不使用多线程的标准流:
List<ParamsDTO> paramsList = listOfPaths.stream().map(p -> readFile(p)).collect(Collectors.toList());
使用并行流来提高性能:
List<ParamsDTO> paramsList = listOfPaths.parallelStream().map(p -> readFile(p)).collect(Collectors.toList());
您已将函数readFile定义为:
public ParamDTO readFile(Path p) {
ParamsDTO params = new ParamsDTO();
params.setParams(Files.readAllBytes(path));
return params;
}
从长远来看,您可能希望超越它,根据磁盘类型控制并行度并获得更多控制,使用Java 5执行程序来管理线程池特性以及普通可运行或未来任务运行。