7

だから私はを返すメソッドを持っていますCompletableFuture。戻る前に、このメソッドは完了thenAccept後に実行されるブロックを追加CompletableFutureします。

このメソッドの呼び出し元は、別のブロックも追加しthenAcceptます。明らかに、これは複数の連鎖呼び出しで続行できます。

実行された呼び出しCompletionStageによって返される順序は? thenAcceptそれらが追加された順序であることが保証されていますか? そうでない場合、それらが追加された順序で実行されることをどのように保証できますか?

PS: 私はCompletableFuture、この記事に関する私自身の経験に基づいて、これを求めています。

4

1 に答える 1

9

完了ステージの依存関係をチェーンすることでモデル化しています。A2 つのアクションおよびBを別のアクションにチェーンする場合、関係およびCを定義しますが、 と の間には関係がないため、順序関係を含め、それらの間に関係はありません。他の後に実行します。A → CB → CAB

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

もちろん、それについての保証はありません。


2 つのコンシューマー間の依存関係を強制するには、それらを適切に連鎖させる必要があります。

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();

ここで、2 番目のコンシューマーは と にチェーンされbasenextから結果を受け取りますが、の完了baseに依存しnextます (渡す結果がない場合は、通常は必要ありません。そのような場合は、設計を再考する必要があるかもしれません)。シナリオ)。

または、最初の値を値を通過する に変換することもできます。そのため、 を介してチェーンしてConsumer、別のステージをチェーンできるようにすることができます。FunctionthenApplythenAccept

于 2016-06-20T09:58:23.263 に答える