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.