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();
    }
}
Jake Walsh
źródło
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);
hoaz
źródło
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);
Andrejs
źródło
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();
Dave
źródło
-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.

Alex Worden
źródło
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();
AlexV
źródło
3
Nie sądzę, żeby to było w podstawowych bibliotekach Java. Jakiej zależności zewnętrznej używa?
Jorn