Home > database >  How can I consolidate each thread result - java
How can I consolidate each thread result - java

Time:12-12

I want execute some java logic with multiple threads and that method return a List. So finally I want all threads result into single List? Is it possible with Java ExecutorService or Multithreading ? or any other java frameworks ?

CodePudding user response:

There are different ways to do it, here is my suggestion:

Create a list of Callable (see more about it in the docs):

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

Add your tasks to this list:

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

Then invoke those Callables by passing them to the invokeAll() method of ExecutorService and receive a List of Future<Object>. For example:

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

You can then get each of the thread results by getting them via index call from the result list - in the same order as which you passed them to your Callable list.

So, to get the result of the first thread that you passed to the Callable list, simply do:

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

Finally, you can collect all results in a single list as you wish.

Also, this is a helpful article on how to use ExecutorService (and remember to shutdown the Executor after you finish working with it, as explained here).

CodePudding user response:

I want execute some java logic with multiple threads and that method return a List. So finally I want all threads result into single List?

There are a couple of ways that I can think of to do this. One way would be to pass a BlockingQueue into all of the jobs. Then they each can be adding results into the same collection.

Any other solution means that each job returns a List and as you join with the jobs you add the per-job list into a final list.

ExecutorService threadPool = Executors.newFixedThreadPool(5);
List<Future<List<Foo>>> futures = new ArrayList<>();
for (int i = 0; i < NUM_JOBS; i  ) {
    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
    // we add all of the results from the job list into the final list
    finalList.addAll(future.get());
}

This waits for each of the jobs in order. If you want to add the results into the list as they finish then you can use a ExecutorCompletionService.

  • Related