Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute multiple queries in parallel via Streams

I am having the following method:

public String getResult() {

        List<String> serversList = getServerListFromDB();

        List<String> appList = getAppListFromDB();

        List<String> userList = getUserFromDB();

        return getResult(serversList, appList, userList);
    }

Here I am calling three method sequentially which in turns hits the DB and fetch me results, then I do post processing on the results I got from the DB hits. I know how to call these three methods concurrently via use of Threads. But I would like to use Java 8 Parallel Stream to achieve this. Can someone please guide me how to achieve the same via Parallel Streams?

EDIT I just want to call the methods in parallel via Stream.

private void getInformation() {
    method1();
    method2();
    method3();
    method4();
    method5();
}
like image 319
Zeeshan Avatar asked Nov 11 '15 11:11

Zeeshan


2 Answers

You may utilize CompletableFuture this way:

public String getResult() {

    // Create Stream of tasks:
    Stream<Supplier<List<String>>> tasks = Stream.of(
            () -> getServerListFromDB(),
            () -> getAppListFromDB(),
            () -> getUserFromDB());

    List<List<String>> lists = tasks
         // Supply all the tasks for execution and collect CompletableFutures
         .map(CompletableFuture::supplyAsync).collect(Collectors.toList())
         // Join all the CompletableFutures to gather the results
         .stream()
         .map(CompletableFuture::join).collect(Collectors.toList());

    // Use the results. They are guaranteed to be ordered in the same way as the tasks
    return getResult(lists.get(0), lists.get(1), lists.get(2));
}
like image 64
Tagir Valeev Avatar answered Oct 17 '22 01:10

Tagir Valeev


As already mentioned, a standard parallel stream is probably not the best fit for your use case. I would complete each task asynchronously using an ExecutorService and "join" them when calling the getResult method:

ExecutorService es = Executors.newFixedThreadPool(3);

Future<List<String>> serversList = es.submit(() -> getServerListFromDB());
Future<List<String>> appList = es.submit(() -> getAppListFromDB());
Future<List<String>> userList = es.submit(() -> getUserFromDB());

return getResult(serversList.get(), appList.get(), userList.get());
like image 39
assylias Avatar answered Oct 17 '22 00:10

assylias