主要可完成未来完成后如何同时调用多个可完成未来

问题描述

下面如何增强功能,其中getB,getC,getD与A具有依赖关系,并且要求在调用之前等待A完成。 但是我希望在A完成后同时致电B C D。

谢谢所有帮助

注意:所有dbService返回一个completableFuture

CompletableFuture<List<A>> a= dbService.getA(request);
a.thenApply(a-> {
                try {
                    return dbService.getB(a);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    return null;
                }
            })
            .thenAccept (result->{
                //do something with B
            });

a.thenApply(a-> {
                try {
                    return dbService.getC(a);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    return null;
                }
            })
            .thenAccept (result->{
                //do something with C
            });

a.thenApply(a-> {
                try {
                    return dbService.getD(a);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    return null;
                }
            })
            .thenAccept (result->{
                //do something with D
            });

解决方法

如果您不关心B,C,D的收益,那么:

CompletionStage<List<A>> aFuture = dbService.getA(request);
aFuture.whenCompleteAsync((a,ex) -> {
    if (ex != null) {
        dbService.getB(a);
        // ...
    } else {
        // ...
    }
});
aFuture.whenCompleteAsync((a,ex) -> {
    if (ex != null) {
        dbService.getC(a);
        // ...
    } else {
        // ...
    }
});
aFuture.whenCompleteAsync((a,ex) -> {
    if (ex != null) {
        dbService.getD(a);
        // ...
    } else {
        // ...
    }
});

您的程序将在dbService.getA(request)开始后立即返回主事件循环,即,甚至还没有完成。当完成 时,由于whenComplete,这3个块中的每一个都在不同的线程上执行(由于已被Async排队) )。

如果您要做想要用B,C和D的收益做某事,那么:

CompletionStage<List<A>> aFuture = dbService.getA(request);

CompletionStage<B> bFuture = aFuture.thenApplyAsync(a -> {
    return dbService.getB(a);
});
CompletionStage<C> cFuture = aFuture.thenApplyAsync(a -> {
    return dbService.getC(a);
});
CompletionStage<D> dFuture = aFuture.thenApplyAsync(a -> {
    return dbService.getD(a);
});

CompletionStage<Something> sFuture = bFuture.thenCompose(b -> {
    cFuture.thenCompose(c -> {
        dFuture.thenApply(d -> {
            // do something with b,c,d
            return new Something();
        });
    });
});
 

您可以使用thenCombine来缩短它,就像thenApply一样等待2个期货:

CompletionStage<List<A>> aFuture = dbService.getA(request);

CompletionStage<B> bFuture = aFuture.thenApplyAsync(a -> {
    return dbService.getB(a);
});
CompletionStage<C> cFuture = aFuture.thenApplyAsync(a -> {
    return dbService.getC(a);
});
CompletionStage<D> dFuture = aFuture.thenApplyAsync(a -> {
    return dbService.getD(a);
});

CompletionStage<Something> sFuture = bFuture.thenCompose(b -> {
    cFuture.thenCombine(dFuture,(c,d) -> {
        // do something with b,d
        return new Something();
    });
});

要将其扩展到任意数量的并发阶段,我喜欢这样使用Spotify's CompletableFutures package

CompletionStage<List<A>> aFuture = dbService.getA(request);

CompletionStage<B> bFuture = aFuture.thenApplyAsync(a -> {
    return dbService.getB(a);
});
CompletionStage<C> cFuture = aFuture.thenApplyAsync(a -> {
    return dbService.getC(a);
});
CompletionStage<D> dFuture = aFuture.thenApplyAsync(a -> {
    return dbService.getD(a);
});

CompletionStage<Something> sFuture = CompletableFutures.combine((bFuture,cFuture,dFuture) -> {
    // do something with b,d
    return new Something();
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...