2016-06-20 14 views
5

Vì vậy, tôi có một phương thức trả về một CompletableFuture. Trước khi trở về, phương thức này thêm một khối với thenAccept được thực hiện sau khi hoàn tất CompletableFuture.Thứ tự trong đó nhiều khối Chấp nhận là của một CompletableFuture được thực hiện

Người gọi của phương pháp này cũng thêm một khối khác với thenAccept. Rõ ràng điều này có thể tiếp tục với nhiều cuộc gọi bị xích.

Thứ tự là CompletionStage được trả lại bởi lệnh gọi thenAccept được thực thi? Nó có được đảm bảo là thứ tự mà chúng được thêm vào không? Nếu không, làm thế nào có thể đảm bảo rằng chúng được thực hiện theo thứ tự mà chúng được thêm vào?

PS: Tôi yêu cầu này dựa trên kinh nghiệm của riêng tôi với CompletableFuture và điều này article

+2

"thenAccept" nghĩa là "CompletableFuture" này được hoàn tất và chỉ sau đó hàm tham số được thực hiện. –

Trả lời

6

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 AB cho một hành động khác, bạn xác định mối quan hệ A → CB → C, nhưng không có mối quan hệ giữa AB 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 basenext, để 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.

Các vấn đề liên quan