Bạn đang mô hình hóa sự phụ thuộc của giai đoạn hoàn thành bằng cách kết nối chúng. Nếu bạn chuỗi hai hành động A
và B
cho một hành động khác, bạn xác định mối quan hệ A → C
và B → C
, nhưng không có mối quan hệ giữa A
và B
và do đó, không có mối quan hệ nào, kể cả mối quan hệ đặt hàng, nói cách khác, bạn có thể 't thậm chí cho rằng ai sẽ chạy theo người kia, tức là
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");
});
sẽ rất có khả năng một cái gì đó in như
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
mặc dù, tất nhiên, không có bảo lãnh về nó.
Để thực thi sự phụ thuộc của bạn giữa hai người tiêu dùng, bạn phải gắn kết chúng một cách thích hợp, ví dụ:
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();
Ở đây, người tiêu dùng thứ hai được xích vào base
và next
, để nhận được kết quả từ base
, nhưng phụ thuộc vào hoàn next
's (mà bạn thường sẽ không yêu cầu nếu không có kết quả để vượt qua-có lẽ bạn muốn suy nghĩ lại về thiết kế của mình, nếu bạn có kịch bản như vậy).
Cách khác, bạn có thể chuyển đổi Consumer
thành Function
đầu tiên thông qua giá trị, để bạn có thể chuỗi nó qua thenApply
, để cho phép chuỗi khác thenAccept
khấu hao.
"thenAccept" nghĩa là "CompletableFuture" này được hoàn tất và chỉ sau đó hàm tham số được thực hiện. –