并行迁移巨大的 XML 文件列表

Migrate list of huge XML files in parallel

我有代码:

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 );
        }
    } );
}

固定大小 ExecutorServiceBlockingQueue 轮询 (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 ) );
}

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

鉴于数字是固定的,该队列没有任何好处。你不需要它。如果不断有新文件进来,您将需要它。

线程数看起来也有效。但它真的取决于 OS 和 JVM 版本来获得最佳数字。你可能宁愿做一些实验来确定。

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

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

在你的情况下队列在没有解决任何问题之间 purpose.Before 跳转到编码分析处理大文件的真正瓶颈。

处理文件涉及从磁盘读取、处理(例如解析 XML 和转换),然后写回 disk.So 这是一个更好的权衡 I/O,更好的 CPU 使用,以及更好的内存使用。要知道 进行分析以监控 CPU 使用情况、内存使用情况和 I/O 效率很重要。

  • 从磁盘读取数据可能I/O-繁重。
  • 将读取的数据存储在Java堆内存中进行处理可以是内存- 重.
  • 解析和转换数据可能CPU-繁重。
  • 将处理后的数据写回磁盘可能I/O-繁重。