Java短路完全未来

Java短路完全未来,java,multithreading,completable-future,Java,Multithreading,Completable Future,我正试图找到一种方法,根据具体情况跳过可完成的未来 比如说 public CompletableFuture<Void> delete(Long id) { CompletableFuture<T> preFetchCf = get(id); CompletableFuture<Boolean> cf1 = execute(); /*This is where I want different execution path, if r

我正试图找到一种方法,根据具体情况跳过可完成的未来

比如说

public CompletableFuture<Void> delete(Long id) {
    CompletableFuture<T> preFetchCf = get(id);
    CompletableFuture<Boolean> cf1 = execute();

    /*This is where I want different execution path, if result of this future is true go further, else do not*/

    // Execute this only if result of cf1 is true
    CompletableFuture<T> deleteCf = _delete(id);
    // Execute this only if result of cf1 is true
    CompletableFuture<T> postDeleteProcess = postDelete(id);
}
public CompletableFuture delete(长id){
CompletableFuture预取cf=get(id);
CompletableFuture cf1=execute();
/*这就是我想要不同执行路径的地方,若这个未来的结果是真的,那个么继续前进,否则就不要*/
//仅当cf1的结果为真时才执行此操作
CompletableFuture deleteCf=\u delete(id);
//仅当cf1的结果为真时才执行此操作
CompletableFuture postDeleteProcess=postDelete(id);
}

实现这一点的好方法是什么?

我将准备一个不同于您在问题中使用的示例,因为从读者的角度来看,您的代码的意图并不十分清楚

首先假设存在一个提供星球大战角色名称的
CompletableFuture

CompletableFuture<String> character = CompletableFuture.completedFuture("Luke");
请注意,我将
CompletableFuture
包装在一个
Supplier
中,以避免它们被急切地评估(这就是所谓的概念)

现在,我转到我的异步链:

character.thenApply(c -> isJedi(c))
            .thenCompose(isJedi -> isJedi ? thunk1.get() : thunk2.get())
            .whenComplete((answer, error) -> System.out.println(answer));
使用
然后编写
让我根据布尔结果选择一条路径。在那里,我评估其中一个Thunk,并使它为我关心的路径创建一个新的
CompletableFuture

这将在屏幕上显示“这家伙是绝地武士”


因此,我相信您正在寻找的是
然后编写
方法。

不确定我是否理解您的目标,但为什么您不按照您在评论中所说的那样继续使用未来链接?类似这样的事情,只是为了说明:

公共类AppTest{
@试验
公共无效testCompletableFutures(){
整数id=(int)Math.random()*1000;
CompletableFuture testing=AppTest.execute()
.ThenAcceptsSync(结果->{
System.out.println(“结果为:”+Result);
如果(结果)
AppTest.delete(id);
其他的
抛出新的运行时异常(“执行失败”);
})
.ThenApplySync(结果->AppTest.postDelete())
.ThenAcceptsSync(postDeleteResult->{
if(postDeleteResult)
System.out.println(“删除后清理成功”);
其他的
抛出新运行时异常(“删除后失败”);
});
}
私有静态布尔postDelete(){
System.out.println(“删除后清理”);
返回Math.random()>0.3;
}
私有静态可完成未来删除(int i){
System.out.println(“删除id=“+i”);
返回CompletableFuture.completedFuture(true);
}
私有静态CompletableFuture execute(){
返回CompletableFuture.supplyAsync(()->Math.random()>0.5);
}
}
当然,这在现实生活中没有多大意义,但我认为它可以展示一个概念


如果您想跳过
之后的第二个调用,请根据结果执行
,这显然是不可能的,因为您需要该结果。关键是,您是否跳过该操作对您来说应该无关紧要,因为它是异步的,您不会阻止等待该结果。

如果(!cf1.get()){return…}将阻止get()。是-如果需要结果来决定做什么(或不做什么),则必须等待接下来。这破坏了未来链接的目的。对于最后两个调用,您实际上不需要
CompletableFutures
,是吗?看起来
Runnable
s就足够了?这不是asnc编程的方式。你想将你的未来链接为非阻塞。如果你想对它进行评估,你最终需要调用
get
,因为你已经开始了另外两个并发操作iiuc,Edwin的答案听起来确实像你在寻找的。否则,我根本不认为
completablefuture
是前进的方向。@RohitJain好吧,我想我误解了你的问题。我又看了一遍,找到了一个更好的答案。我希望这就是你要找的。
character.thenApply(c -> isJedi(c))
            .thenCompose(isJedi -> isJedi ? thunk1.get() : thunk2.get())
            .whenComplete((answer, error) -> System.out.println(answer));