如何合并每个线程结果 - java

Posted

技术标签:

【中文标题】如何合并每个线程结果 - java【英文标题】:How can I consolidate each thread result - java 【发布时间】:2022-01-14 15:07:25 【问题描述】:

我想用多个线程执行一些 java 逻辑,并且该方法返回一个列表。所以最后我希望所有线程都进入单个列表? Java ExecutorService 或 Multithreading 是否有可能?或任何其他 java 框架?

【问题讨论】:

【参考方案1】:

有不同的方法可以做到这一点,这是我的建议:

创建Callable 的列表(在docs 中查看更多信息):

List<Callable<Object>> callables = new ArrayList<>();

将您的任务添加到此列表中:

callables.add(() -> 
            // do something
        );

然后通过将它们传递给ExecutorServiceinvokeAll() 方法来调用这些可调用对象,并接收Future&lt;Object&gt; 的列表。例如:

ExecutorService executor = Executors.newFixedThreadPool(5);
List<Future<Object>> results = executor.invokeAll(callables);

然后,您可以通过索引调用从 result 列表中获取每个线程结果 - 与将它们传递到 Callable 列表的顺序相同。

因此,要获取传递给 Callable 列表的第一个线程的结果,只需执行以下操作:

  CastedResult result = (CastedResult) results.get(0).get(); 

最后,您可以根据需要将所有结果收集到一个列表中。

此外,这对于如何使用 ExecutorService 很有帮助(请记住在完成使用后关闭 Executor,如此处所述)。

【讨论】:

【参考方案2】:

我想用多个线程执行一些 java 逻辑,并且该方法返回一个列表。所以最后我希望所有线程都变成一个列表?

我可以想到几种方法来做到这一点。一种方法是将BlockingQueue 传递给所有工作。然后他们每个人都可以将结果添加到同一个集合中。

任何其他解决方案可能意味着每个作业都会返回一个List,并且当您加入作业时,您会将每个作业列表添加到最终列表中。

ExecutorService threadPool = Executors.newFixedThreadPool(NUM_THREADS);
List<Future<List<Foo>>> futures = new ArrayList<>();
for (int i = 0; i < NUM_JOBS; i++) 
    // add another job to the thread-pool and record the future
    futures.add(threadPool.submit(new Callable<List<Foo>>() 
        @Override
        public List<Foo> call() throws Exception 
            // create the list here
            return list;
        
    );

// shutdown the pool but the jobs continue running
threadPool.shutdown();
List<Foo> finalList = new ArrayList<Foo>();
for (Future<List<Foo>> future : futures) 
    // calling get waits for each job to finish in order
    // we add all of the results from the job list into the final list
    finalList.addAll(future.get());

这会按顺序等待每个作业。如果您想在结果完成后将结果添加到列表中,则可以使用ExecutorCompletionService。

【讨论】:

以上是关于如何合并每个线程结果 - java的主要内容,如果未能解决你的问题,请参考以下文章

产生工作线程

多线程 fork/join 并行计算

Java多线程Java的MapReduce框架ForkJoin

如何在java中合并来自两个不同数据库的两个不同结果集

Java 分支合并(ForkJoin)

多个EXCEL的CSV文件合并时会把每个文件的表头重复合并到结果文件里,能否让合并结果只有一个表头呢?