Jak stworzyć pełną przyszłość w Javie


87

Jaki jest najlepszy sposób na zbudowanie pełnej przyszłości w Javie? Zaimplementowałem własne CompletedFutureponiżej, ale miałem nadzieję, że coś takiego już istnieje.

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
Najlepiej go nie tworzyć! ;-) Dlaczego potrzebujesz implementować Future? Czy nie możesz zamiast tego użyć istniejących obiektów, które zwracają przyszłość?
assylias

1
Podejrzewam, że żaden nie istnieje, ponieważ nigdy nie widziałem powodu, aby go mieć. Może mógłbyś wyjaśnić, co próbujesz zrobić?
Peter Lawrey

1
@PeterLawrey Przypuszczam, że potrzebuje go do jakiegoś API, które z jakiegoś pokręconego powodu chce pracować z przyszłością, mimo że tak naprawdę potrzebuje tylko jej wartości. Albo potrzebuje go do kpin. Przynajmniej to jedyne powody, jakie mogę sobie wyobrazić.
Sześcienny

9
Testy jednostkowe byłyby całkowicie dobrym powodem, aby tego chcieć - wyszydzanej usługi zwracającej przyszłość z wartościami testowymi.
Louis Wasserman,

3
@Sześcienny. A co by było, gdybyś miał metodę, która akceptuje Callable <T> i kto może, ale nie musi, uruchamiać zadanie asynchronicznie w zależności od dostępnych zasobów lub innych czynników, takich jak opcje, które zostały już dostarczone znacznie wcześniej? Wyobraź sobie, że gdyby Executor.execute (Runnable) zamiast tego wziął Callable <T> jako parametr i zdecydował się go uruchomić w wykonującym wątku, czy implementacja nie musiałaby wtedy tworzyć własnego Future <T>?
Martin Andersson

Odpowiedzi:


66

Apache Commons Lang definiuje podobną implementację, która nazywa się ConstantFuture, możesz ją uzyskać, wywołując:

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

Zobacz odpowiedź Andrejsa poniżej, może to być więcej tego, czego szukasz
nathanfranke

201

W Javie 8 możesz skorzystać z wbudowanego CompletableFuture:

 Future future = CompletableFuture.completedFuture(value);

To dałoby ci pełną przyszłość. Zamiast tego użyj nowej CompletableFuture ().
zafar142003

8
@ zafar142003 OP poprosił o ukończoną przyszłość, nie?
Andrejs

sądząc po klasie w szczegółach pytania (w 2012 r.), myślę, że PO chciał wdrożenia „Completable Future”. Ale myślę, że jest to teraz kwestia dyskusyjna.
zafar142003

Sądząc po klasie w szczegółach pytania, wygląda na to, że OP chciał przyszłości o natychmiastowej wartości. Zobacz, że isDonezawsze zwraca prawdę. Dlatego jest to doskonała odpowiedź.
nathanfranke


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

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

wypisze "foo";

Możesz również mieć Future, który zgłasza wyjątek, gdy wywoływana jest metoda get ():

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

-3

Znalazłem bardzo podobną klasę do twojej w Java rt.jar

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

Pozwala również określić wyjątek, który może zostać wyrzucony po wywołaniu metody get (). Po prostu ustaw to na null, jeśli nie chcesz zgłaszać wyjątku.


2
Ogólnie używanie czegokolwiek w com.sun.*pakiecie nie jest dobrym pomysłem. Te klasy są ogólnie uważane za wewnętrzny szczegół implementacji i mogą ulec zmianie w różnych wersjach języka Java.
James Kingsbery

-6

W Javie 6 możesz użyć:

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

3
Nie sądzę, żeby to było w podstawowych bibliotekach Java. Jakiej zależności zewnętrznej używa?
Jorn
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.