ExecutorService 具有大量任务

Ant*_* J. 2 java multithreading executorservice threadpool

我有一个文件列表和一个分析这些文件的分析器列表。文件数量可能很大(200,000 个),分析器数量可能很大(1000 个)。因此操作总数可能非常大(200,000,000)。现在,我需要应用多线程来加快速度。我遵循了这种方法:

ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
for (File file : listOfFiles) {
  for (Analyzer analyzer : listOfAnalyzers){
    executor.execute(() -> {
      boolean exists = file.exists();
      if(exists){
        analyzer.analyze(file);
      }
    });
  }
}
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)

但这种方法的问题是它从内存中获取了太多内容,我想有更好的方法来做到这一点。我还是java和多线程的初学者。

Abu*_*sar 5

200M 任务将驻留在哪里?我希望不在内存中,除非您计划以分布式方式实现您的解决方案。同时,您需要实例化一个ExecutorService不会积累大量队列的实例。创建服务时与“调用者运行策略”(请参阅​​此处)一起使用。如果您尝试在队列已满时将另一个任务放入队列中,您最终将自己执行它,这可能正是您想要的。

OTOH,既然我更认真地看待你的问题,为什么不同时分析单个文件呢?那么队列永远不会大于分析器的数量。坦率地说,这就是我要做的,因为我想要一个可读的日志,其中在加载每个文件时以正确的顺序包含一条消息。

我很抱歉没有提供更多帮助:

analysts.stream().map(analyst -> executor.submit(() -> analyst.analyze(file))).map(Future::get);

基本上,为单个文件创建一堆 future,然后等待所有这些 future,然后再继续。