以多线程模式读取多个文件



我有 ArrayList。它包含大约20,000个文件路径元素。

private List<Path> listOfPaths = new ArrayList<>();

我想在多线程模式下阅读这些路径上的文件内容。问题在于此代码运行速度很慢。如何选择几个线程,以便每个线程读取文件并将其写入dto?如何解决一个线程开始处理文件的问题,以使另一个线程与同一文件不执行相同的操作?

您可能可以在较小的块中将作品分开,每个线程处理所有文件的一部分。每个线程都会有自己的数据列表进行处理和处理的数据列表,以避免尝试同时读取相同数据的任何风险。所有线程完成后,您将升级结果。

实际上,您可以让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());

您将函数定义为以下位置:

public ParamDTO readFile(Path p) {
    ParamsDTO params = new ParamsDTO();
    params.setParams(Files.readAllBytes(path));
    return params;
}

从长远来看,您可能希望超越它,根据磁盘类型的类型控制并行性的水平,并获得更多的控制权,使用Java 5执行者来管理线程池特征和普通的可运行或期货要运行任务。

我创建了IOPOOL,以不用IO操作来阻止common-pool(默认在并行流操作上使用(。通常,如果您正在执行IO操作,则建议您可以创建core-count* 2线程,但是确实有限制。

您可以像下面这样做。这不会按顺序处理您的文件列表。

 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

最新更新