并行迁移大型XML文件列表

时间:2017-06-25 12:08:26

标签: java multithreading concurrency executorservice

我有代码:

final int numOfThreads = Runtime.getRuntime().availableProcessors() + 1;
final ExecutorService exec = Executors.newFixedThreadPool( numOfThreads );
final int numOfFiles = listOfAllFiles.size();
final BlockingQueue<File> queue = new ArrayBlockingQueue<File>( numOfFiles, false, listOfAllFiles );

for ( int i = 0; i < numOfThreads; i++ ) {
    exec.execute( () -> {
        File file = null;

        while ( (file = queue.poll()) != null ) {
            migrate( file );
        }
    } );
}

来自ExecutorService的固定大小BlockingQueue个民意调查(XML)文件,以便迁移它们。由于大多数文件都很大(多个GB),因此每个线程都在进行大量的I / O.

队列是否必要?我不能这样做:

final int numOfThreads = Runtime.getRuntime().availableProcessors() + 1;
final ExecutorService exec = Executors.newFixedThreadPool( numOfThreads );

for ( final File file : listOfAllFiles ) {
    exec.execute( () -> migrate( file ) );
}

我也想知道固定的线程池是否是理想的选择?

3 个答案:

答案 0 :(得分:2)

具有固定大小的线程池的ExecutorService是一个不错的选择。但是,我认为您应该将池大小作为调整参数。

问题在于我们不知道migrateFile是CPU密集型,I / O密集型,内存(堆大小)密集型还是某种组合。最佳线程可能取决于此。最好的策略是做一些实验。

答案 1 :(得分:1)

鉴于numper是固定的,该队列不会带来任何好处。你不需要它。如果新文件继续存在,您将需要它。

线程数也看起来有效。但它确实取决于操作系统和JVM版本以获得最佳数量。你可能宁愿做一些实验来确定。

答案 2 :(得分:0)

在你的案例中,队列之间没有解决任何目的。在跳转到编码之前,分析处理大文件的真正瓶颈。

处理文件涉及从磁盘读取,处理(例如解析XML和转换),以及写回磁盘。因此,在更好的I / O,更好的CPU使用率和更好的内存方面,这是一个权衡。用法。要知道进行性能分析以监控CPU使用率,内存使用率和I / O效率非常重要。

  • 从磁盘读取数据可能是I / O大量的。
  • 将读取数据存储在Java堆内存中以处理它们可以是内存 - 重。
  • 解析&amp;转换数据可能会占用大量CPU资源。
  • 将处理后的数据写回磁盘可能是I / O大量的。