Java 通过流并行执行多个查询

Java 通过流并行执行多个查询,java,parallel-processing,java-8,java-stream,Java,Parallel Processing,Java 8,Java Stream,我有以下方法: public String getResult() { List<String> serversList = getServerListFromDB(); List<String> appList = getAppListFromDB(); List<String> userList = getUserFromDB(); return getResult(serversLi

我有以下方法:

public String getResult() {

        List<String> serversList = getServerListFromDB();

        List<String> appList = getAppListFromDB();

        List<String> userList = getUserFromDB();

        return getResult(serversList, appList, userList);
    }

不太清楚您的意思是什么,但如果您只想在这些列表上并行运行一些进程,您可以执行以下操作:

    List<String> list1 = Arrays.asList("1", "234", "33");

    List<String> list2 = Arrays.asList("a", "b", "cddd");

    List<String> list3 = Arrays.asList("1331", "22", "33");

    List<List<String>> listOfList = Arrays.asList(list1, list2, list3);

    listOfList.parallelStream().forEach(list -> System.out.println(list.stream().max((o1, o2) -> Integer.compare(o1.length(), o2.length()))));
List list1=Arrays.asList(“1”、“234”、“33”);
list2=Arrays.asList(“a”、“b”、“cddd”);
list3=Arrays.asList(“1331”、“22”、“33”);
listOfList=Arrays.asList(list1、list2、list3);
listOfList.parallelStream().forEach(list->System.out.println(list.stream().max((o1,o2)->Integer.compare(o1.length(),o2.length()));

(它将打印每个列表中最长的元素)。

foreach
用于
副作用
,您可以在
并行流上调用
foreach
。例:

listOfTasks.parallelStream().foreach(list->{
  submitToDb(list);
});
然而,
parallelStream
使用了公共的
ForkJoinPool
,这对于
IO绑定的
任务来说无疑是不好的

考虑使用
CompletableFuture
,并提供适当的
ExecutorService
。它提供了更大的灵活性(
延续
,配置)。例如:

ExecutorService ExecutorService=Executors.newCachedThreadPool();
List allFutures=new ArrayList();
for(查询:查询){
CompletableFuture查询=CompletableFuture.SupplySync(()->{
//向数据库提交查询
返回结果;
}(执行人服务);
添加(查询);
}
CompletableFuture all=CompletableFuture.allOf(allFutures.toArray(新的CompletableFuture[allFutures.size()]);

如前所述,标准并行流可能不是最适合您的用例的。我将使用ExecutorService异步完成每个任务,并在调用getResult方法时“加入”它们:

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());
Executors服务=Executors.newFixedThreadPool(3);
Future serversList=es.submit(()->getServerListFromDB());
Future appList=es.submit(()->getAppListFromDB());
Future userList=es.submit(()->getUserFromDB());
返回getResult(serversList.get()、appList.get()、userList.get());

您可以通过以下方式利用
CompletableFuture

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));
}
公共字符串getResult(){
//创建任务流:
Stream tasks=Stream.of(
()->getServerListFromDB(),
()->getAppListFromDB(),
()->getUserFromDB());
列表=任务
//提供所有要执行的任务并收集可完成的任务
.map(CompletableFuture::SupplySync).collect(Collectors.toList())
//加入所有CompletableFutures以收集结果
.stream()
.map(CompletableFuture::join).collect(Collectors.toList());
//使用结果。它们保证以与任务相同的方式排序
返回getResult(lists.get(0)、lists.get(1)、lists.get(2));
}

您希望最终结果是什么?最后一个字符串是什么?我只想同时调用上述三个方法。这只是一个例子。您上次的编辑会使问题更加混乱…使用性能正确的数据库代码可能会节省更多时间,例如不为每个查询打开完全独立的连接和事务。如果您需要访问子表,有时这是不可能的。例如,我有一个大约有10个子表的查询,尝试将其转换为一个大规模联接要比多个简单的select语句慢得多。而且代码更易于管理。但是
CompletableFuture
并不比Java8之前的用法好:
Future-appList=es.submit(()->getAppListFromDB())
@Holger-hum-看起来我真的被迷住了。
Collections.max(list,Comparator.comparingit(String::length))
或使用
import static
max(list,comparingInt(String::length))
..@Holger这只是一个并行某个进程而不声明
max..length
issue decision
parallelStream
(使用fork-join-pool下划线)的示例,它对I/O绑定任务的执行效果不好。这会打开3个新线程,每个供应商一个吗?如果答案是肯定的,每个线程是否会打开一个新的数据库连接?这个解决方案对我很有效。杰出的但是我不理解这部分
.map(CompletableFuture::supplyAsync).collect(Collectors.toList()).stream().map(CompletableFuture::join)
为什么要先收集列表,然后再收集流,然后再收集映射?顺便说一句,我删除了这两个收集和流的部分,然后事情就不起作用了。你能解释一下吗?
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());
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));
}