繁体   English   中英

在多线程模式下读取多个文件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM