[英]Reading multiple files in multithreaded mode
我有ArrayList
。 它包含大约20,000个文件路径元素。
private List<Path> listOfPaths = new ArrayList<>();
我想以多线程模式读取这些路径上文件的内容。 问题在于此代码运行非常缓慢。 如何选择几个线程,以便每个线程读取文件并将其写入dto
? 如何解决一个线程开始处理文件的问题,以便另一个线程对同一文件不做同样的事情?
我创建ioPool的目的是为了不阻止io操作使用common-pool(默认用于并行流操作)。 通常建议您在执行io操作时,可以创建core-count* 2
线程,但实际上它在io方面受到限制,就像其他人提到的那样。
您可以按照以下步骤进行操作。 这不会按顺序处理您的文件列表。
ForkJoinPool ioPool = new ForkJoinPool(8);
ForkJoinTask<?> tasks = ioPool.submit(
() -> pathList.parallelStream().forEach(//your code here);
tasks.get(); // this blocks until all threads finishes in the pool
您可以将工作分成较小的块,每个线程处理所有文件的一部分。 每个线程都有自己要处理的数据的子列表和已处理的数据的列表,以避免尝试同时读取/写入相同数据的任何风险。 当所有线程都完成后,您将确定结果。
实际上,您可以让Java 8并行流为您完成拆分/合并等艰巨的工作。
使用标准流而不使用多个线程:
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执行程序来管理线程池特征以及任务的普通可运行或将来执行。跑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.