So erstellen Sie eine vollständige Zukunft in Java

81

Was ist der beste Weg, um eine abgeschlossene Zukunft in Java zu konstruieren? Ich habe meine eigene CompletedFutureunten implementiert , hoffte aber, dass so etwas bereits existiert.

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
quelle
1
Der beste Weg ist, keinen zu erstellen! ;-) Warum musst du eine Zukunft implementieren? Können Sie nicht vorhandene Objekte verwenden, die stattdessen eine Zukunft zurückgeben?
Assylias
1
Ich vermute, dass es keine gibt, weil ich nie einen Grund gesehen habe, einen zu haben. Vielleicht könnten Sie erklären, was Sie versuchen zu tun?
Peter Lawrey
1
@PeterLawrey Ich nehme an, er braucht es für eine API, die aus irgendeinem verdrehten Grund mit Futures arbeiten möchte, obwohl es wirklich nur seine Werte braucht. Oder er braucht es zum Verspotten. Zumindest sind das die einzigen Gründe, die ich mir vorstellen kann.
Cubic
8
Unit-Tests wären ein guter Grund, dies zu wollen - ein verspotteter Service, der mit Testwerten eine Zukunft zurückgibt.
Louis Wasserman
3
@ Cubic. Wie wäre es, wenn Sie eine Methode hätten, die ein Callable <T> akzeptiert, und die den Job abhängig von verfügbaren Ressourcen oder anderen Faktoren wie Optionen, die bereits viel früher bereitgestellt wurden, asynchron ausführen kann oder nicht? Stellen Sie sich vor, wenn Executor.execute (Runnable) stattdessen ein Callable <T> als Parameter verwendet und beschlossen hat, es im ausführenden Thread auszuführen, müsste die Implementierung dann nicht seine eigene Future <T> erstellen?
Martin Andersson

Antworten:

64

Apache Commons Lang definiert eine ähnliche Implementierung, die ConstantFuture heißt. Sie erhalten sie, indem Sie Folgendes aufrufen:

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

In Java 8 können Sie die integrierte CompletableFuture verwenden:

 Future future = CompletableFuture.completedFuture(value);
Andrejs
quelle
Dies würde Ihnen eine abgeschlossene Zukunft geben. Verwenden Sie stattdessen new CompletableFuture ().
zafar142003
6
@ zafar142003 OP fragte nach einer abgeschlossenen Zukunft, nein?
Andrejs
Nach der Klasse in den Fragendetails (2012) zu urteilen, wollte das OP meiner Meinung nach eine Implementierung von 'CompletableFuture'. Aber ich denke, das ist jetzt ein strittiger Punkt.
zafar142003
1
FutureTask<String> ft = new FutureTask<>(() -> "foo");
ft.run();

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

druckt "foo" aus;

Sie können auch eine Zukunft haben, die eine Ausnahme auslöst, wenn get () aufgerufen wird:

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

Ich habe eine sehr ähnliche Klasse wie Ihre in der Java-Datei rt.jar gefunden

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

Hier können Sie auch eine Ausnahme angeben, die beim Aufrufen von get () ausgelöst werden kann. Setzen Sie das einfach auf null, wenn Sie keine Ausnahme auslösen möchten.

Alex Worden
quelle
2
Im Allgemeinen com.sun.*ist es keine gute Idee , etwas im Paket zu verwenden. Diese Klassen werden im Allgemeinen als internes Implementierungsdetail betrachtet und können sich je nach Java-Version ändern.
James Kingsbery
-6

In Java 6 können Sie Folgendes verwenden:

Promise<T> p = new Promise<T>();
p.resolve(value);
return p.getFuture();
AlexV
quelle
2
Ich glaube nicht, dass das in den Java-Kernbibliotheken ist. Welche externe Abhängigkeit wird verwendet?
Jorn