I am using completablefuture to be returned from an async thread in springboot application. My implementation is below. From my understanding a new thread should be started for each item in list and should process parallely. I understand .get will block the execution but as it is parallely running still i dont see any improvement in performance. Any suggestions on below please to improve the performance?
ServiceA.java
@Autowired
ServiceB serviceb;
public List<String> getNames(List<Item> items) {
List<CompletableFuture<String>> list = new ArrayList<>();
List<String> returnList = new ArrayList<>();
for( Item item: items) {
CompletableFuture<String> getItemName = serviceb.doProcess(item);
list.add(getItemName):
}
for( CompletableFuture name : list) {
returnList.add(name.get());
}
return returnList;
}
ServiceB.java
Class ServiceB {
@Async
Public CompletableFuture<String> doProcess(Item item)
{
//do process
}
You could call allOf to wait for all results. This will wait for all CompletableFuture to complete.
List<String> returnList = new ArrayList<>(items.size());
CompletableFuture<String>[] tasks = items.stream()
.map(value-> serviceb.doProcess(value).thenApply(returnList::add))
.toArray(CompletableFuture[]::new);
// wait for all tasks to finish
CompletableFuture.allOf(tasks).get(50, TimeUnit.SECONDS);
// return the results
return returnList;
Second solution would be to use an reactive approach like publisher/subscriber pattern (Spring WebFlux or JavaRx). This way your application would have little/no waiting operation. But this would affect your application architecture.
One Advice: In order to create an CompletableFuture
use the constructor with ExecutorService in order to keep in check number of threads and have control over running threads or when application shuts down.