Cách tạo tương lai hoàn chỉnh trong java


82

Cách tốt nhất để xây dựng một tương lai hoàn chỉnh trong Java là gì? Tôi đã thực hiện của riêng tôi CompletedFuturebên dưới, nhưng đã hy vọng một cái gì đó như thế này đã tồn tại.

public class CompletedFuture<T> implements Future<T> {
    private final T result;

    public CompletedFuture(final T result) {
        this.result = result;
    }

    @Override
    public boolean cancel(final boolean b) {
        return false;
    }

    @Override
    public boolean isCancelled() {
        return false;
    }

    @Override
    public boolean isDone() {
        return true;
    }

    @Override
    public T get() throws InterruptedException, ExecutionException {
        return this.result;
    }

    @Override
    public T get(final long l, final TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
        return get();
    }
}

1
Cách tốt nhất là đừng tạo một cái! ;-) Tại sao bạn cần triển khai Tương lai? Bạn không thể sử dụng các đối tượng hiện tại trả về tương lai?
assylias 13/12/12

1
Tôi nghi ngờ không tồn tại bởi vì tôi chưa bao giờ thấy lý do để có một cái. Có lẽ bạn có thể giải thích những gì bạn đang cố gắng làm?
Peter Lawrey 13/12/12

1
@PeterLawrey Tôi cho rằng anh ấy cần nó cho một số API vì một số lý do khó hiểu muốn làm việc với tương lai mặc dù nó thực sự chỉ cần các giá trị của nó. Hoặc anh ta cần nó để chế nhạo. Ít nhất đó là những lý do duy nhất tôi có thể tưởng tượng.
Khối

9
Các bài kiểm tra đơn vị sẽ là một lý do hoàn toàn chính đáng để muốn điều này - một dịch vụ giả mạo trả lại một tương lai với các giá trị kiểm tra.
Louis Wasserman

3
@Cubic. Còn nếu bạn có một phương thức chấp nhận một <T> có thể gọi và ai có thể hoặc không thể chạy công việc một cách không đồng bộ phụ thuộc vào các tài nguyên có sẵn hoặc các yếu tố khác, chẳng hạn như các tùy chọn đã được cung cấp trước đó? Hãy tưởng tượng nếu Executor.execute (Runnable) lấy một tham số Callable <T> thay thế và quyết định chạy nó trong chuỗi thực thi, thì việc triển khai có cần tạo Future <T> của riêng mình không?
Martin Andersson

Câu trả lời:


65

Apache Commons Lang định nghĩa cách triển khai tương tự được gọi là ConstantFuture, bạn có thể lấy nó bằng cách gọi:

Future<T> future = ConcurrentUtils.constantFuture(T myValue);

Xem câu trả lời của Andrejs dưới đây, nó có thể là nhiều hơn những gì bạn đang tìm kiếm
nathanfranke

194

Trong Java 8, bạn có thể sử dụng CompletableFuture tích hợp sẵn:

 Future future = CompletableFuture.completedFuture(value);

Điều này sẽ cung cấp cho bạn một tương lai hoàn chỉnh. Thay vào đó, hãy sử dụng CompletableFuture () mới.
zafar142003 Ngày

8
@ zafar142003 OP yêu cầu một tương lai hoàn thành, không?
Andrejs

đánh giá của lớp trong chi tiết câu hỏi (vào năm 2012), tôi nghĩ OP muốn triển khai 'CompletableFuture'. Nhưng tôi đoán, đây là một điểm tranh luận.
zafar142003 Ngày

Đánh giá theo lớp trong chi tiết câu hỏi, có vẻ như OP muốn có một Tương lai với giá trị tức thì. Xem rằng isDoneluôn luôn trả về true. Do đó, đây là một câu trả lời tuyệt vời.
nathanfranke


2
FutureTask<String> ft = new FutureTask<>(() -> "foo");
ft.run();

System.out.println(ft.get());

sẽ in ra "foo";

Bạn cũng có thể có Tương lai ném một ngoại lệ khi get () được gọi:

FutureTask<String> ft = new FutureTask<>(() -> {throw new RuntimeException("exception!");});
ft.run();

-3

Tôi đã tìm thấy một lớp rất giống với lớp của bạn trong Java rt.jar

com.sun.xml.internal.ws.util.CompletedFuture

Nó cho phép bạn cũng chỉ định một ngoại lệ có thể được ném khi get () được gọi. Chỉ cần đặt giá trị đó thành null nếu bạn không muốn tạo ra một ngoại lệ.


2
Nói chung, sử dụng bất cứ thứ gì trong com.sun.*gói không phải là một ý tưởng tuyệt vời. Các lớp đó thường được coi là chi tiết triển khai nội bộ và có thể thay đổi trên các phiên bản của Java.
James Kingsbery

-6

Trong Java 6, bạn có thể sử dụng như sau:

Promise<T> p = new Promise<T>();
p.resolve(value);
return p.getFuture();

3
Tôi không nghĩ đó là thư viện lõi của Java. Nó sử dụng phụ thuộc bên ngoài nào?
Jorn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.