CompletableFuture以异步执行多个数据库查询

我想并行执行多个数据库查询,并将结果存储在映射中。我正在尝试这样做,但是访问地图时,地图并未完全填充。

我做错什么了吗?

@{PROC}=/proc/

在此先感谢您的帮助。

climb166 回答:CompletableFuture以异步执行多个数据库查询

在上述方法中,supplyAsync将由ForkJoinPool中的Async线程执行,但是thenApply方法总是由调用线程执行。因此,您的查询将按照非异步的顺序依次运行

  

所有没有显式Executor参数的异步方法都是使用ForkJoinPool.commonPool()执行的(除非它不支持并行度至少为2,在这种情况下,将创建一个新的Thread来运行每个任务)。 / p>

这里是例子

CompletableFuture.supplyAsync(()->{
        System.out.println(Thread.currentThread().getName());
        return "SupplyAsync";
    }).thenAccept(i->{
    System.out.println(Thread.currentThread().getName()+"--"+i);
    });

输出:

ForkJoinPool.commonPool-worker-3
main--SupplyAsync

因此,如果您希望您的进程为Async,则首先使用supplyAsync触发所有三个数据库查询,并在CompletableFuture内捕获输出

CompletableFuture<Set<String>> first =  CompletableFuture.supplyAsync(() -> dbReadService.getCall(phoneNumber,PhoneNumber.class,"ABC",timestamp));

CompletableFuture<Set<String>> second =  CompletableFuture.supplyAsync(() -> dbReadService.getCall(phoneNumber,"XYZ",timestamp));

CompletableFuture<Set<String>> third =  CompletableFuture.supplyAsync(() -> dbReadService.getCall(phoneNumber,"DEF",timestamp));

然后使用其中三个创建流,然后将它们收集到Map

Stream.of(new AbstractMap.SimpleEntry<MapKeyEnums,CompletableFuture<Set<String>>>(MapKeyEnums.ABC,first),new AbstractMap.SimpleEntry<MapKeyEnums,CompletableFuture<Set<String>>>(MapKeyEnums.XYZ,second),CompletableFuture<Set<String>>>(MapKeyEnums.DEF,third))
       .forEach(entry->{
           entry.getValue().thenAccept(val-> instrumentsEdgesMap.put(entry.getKey(),val));
       });
,

返回结果之前,您必须等待期货完成。

尝试类似

    public Map<MapKeyEnums,Set<String>> doDBCalls(String phoneNumber,long timestamp) {

        Map<MapKeyEnums,Set<String>> instrumentsEdgesMap = new EnumMap<>(MapKeyEnums.class);

        CompletableFuture.allOf(
            CompletableFuture.supplyAsync(() -> dbReadService.getCall(phoneNumber,timestamp))
                .thenAccept(x -> instrumentsEdgesMap.put(MapKeyEnums.ABC,x)),CompletableFuture.supplyAsync(() -> dbReadService.getCall(phoneNumber,timestamp))
                .thenAccept(x -> instrumentsEdgesMap.put(MapKeyEnums.XYZ,timestamp))
                .thenAccept(x -> instrumentsEdgesMap.put(MapKeyEnums.DEF,x)))
        .get(); // wait for completion of all three subtasks

        return instrumentsEdgesMap;
    }

本文链接:https://www.f2er.com/3099496.html

大家都在问