2016-06-20 33 views
5

所以我有一个方法返回CompletableFuture。在返回之前,此方法添加一个thenAccept的块,该块在CompletableFuture完成后执行。执行CompletableFuture中多个thenAccept块的顺序是什么

此方法的调用者还添加了另一个块thenAccept。显然这可以继续多个链接的调用。

执行thenAccept调用返回的CompletionStage的顺序是什么?它保证是它们被添加的顺序吗?如果没有,如何保证他们按照添加的顺序执行?

PS:我问这个基础上我自己的经验CompletableFuturearticle

+2

“thenAccept”表示首先完成“this”CompletableFuture,然后才执行参数函数。 –

回答

6

你被串联起来,完成建模阶段的依赖性。如果您将两个动作AB到另一个动作C,您定义的关系A → CB → C,但AB,因此没有关系,没有关系,包括没有排序关系,他们之间,换句话说,你可以“吨甚至认为对方后一个将运行,即

CompletableFuture<String> base=CompletableFuture.supplyAsync(() -> { 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2)); 
    return "source"; 
}); 
base.thenAccept(s -> { 
    System.out.println("entered first consumer in "+Thread.currentThread()); 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1)); 
    System.out.println("leaving first consumer"); 
}); 
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2)); 
base.thenAccept(s -> { 
    System.out.println("entered second consumer in "+Thread.currentThread()); 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1)); 
    System.out.println("leaving second consumer"); 
}); 

很可能会打印类似

entered first consumer in Thread[ForkJoinPool.commonPool-worker-1,5,main] 
entered second consumer in Thread[main,5,main] 
leaving second consumer 
leaving first consumer 

虽然,当然,也没有关于它的担保。


为了强制您在两个消费者之间的依赖关系,您必须适当链接它们,例如,

CompletableFuture<String> base=CompletableFuture.supplyAsync(() -> { 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2)); 
    return "source"; 
}); 
CompletableFuture<Void> next = base.thenAccept(s -> { 
    System.out.println("entered first consumer in "+Thread.currentThread()); 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1)); 
    System.out.println("leaving first consumer"); 
}); 
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2)); 
base.thenAcceptBoth(next, (s,ignored) -> { 
    System.out.println("entered second consumer in "+Thread.currentThread()); 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1)); 
    System.out.println("leaving second consumer"); 
}).join(); 

这里,第二消费者被链接到basenext,从base接受的结果,而是取决于next的完成(你通常如果没有结果传递也许不会要求如果你有这种情况,你想重新考虑你的设计)。

或者,也可以将所述第一ConsumerFunction穿过值,这样就可以通过连锁thenApply它,以允许链接另一个thenAccept阶段到它。

相关问题