Sie könnten eine Methode schreiben, die eine lang andauernde Aufgabe asynchron ausführt. Sie würden dann ein zukünftiges Objekt zurückgeben, das leer ist, aber gefüllt wird, wenn die lang andauernde Aufgabe abgeschlossen ist. In anderen Programmiersprachen wird dies als Versprechen bezeichnet.
Hier ist ein einfaches Beispiel. Ich habe eine Methode namens someLongAsyncOperation
erstellt, die etwas ausführt, das eine Weile dauert. Um dies zu simulieren, schlafe ich nur 3 Sekunden, bevor ich eine Antwort erzeuge.
import java.util.UUID;
import java.util.concurrent.*;
public class Test {
private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
public Future<MyAnswer> someLongAsyncOperation(){
Future<MyAnswer> future = executorService.submit(() -> {
Thread.sleep(3000);
return new MyAnswer(UUID.randomUUID().toString());
});
return future;
}
public static void main(String[] args) throws Exception {
System.out.println("calling someLongAsyncOperation ...");
Future<MyAnswer> future = new Test().someLongAsyncOperation();
System.out.println("calling someLongAsyncOperation done.");
// do something else
System.out.println("wait for answer ...");
MyAnswer myAnswer = future.get();
System.out.printf("wait for answer done. Answer is: %s", myAnswer.value);
executorService.shutdown();
}
static class MyAnswer {
final String value;
MyAnswer(String value) {
this.value = value;
}
}
}
Wenn Sie diese kleine Testklasse ausführen, werden Sie sehen, dass someLongAsyncOperation
kehrt schnell, aber wenn future.get();
Aufruf warten wir auf den Vorgang abzuschließen.
Sie könnten jetzt etwas wie das Starten von mehr als einer longAsyncOperation tun, also würden sie parallel laufen. Und dann warte, bis alle fertig sind.
Funktioniert das als Ausgangspunkt für Sie?
EDIT
Sie someMethod
wie dies implementieren könnte:
public MyAnswer someMethod() throws ExecutionException, InterruptedException {
Future<MyAnswer> future = someLongAsyncOperation(); // kick of async operation
return future.get(); // wait for result
}
, die den Asynchron-Operation synchron wieder machen, indem sie sie anrufen und auf das Ergebnis warten.
EDIT2
Hier ist ein weiteres Beispiel, das warten verwendet/notify:
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test2 {
private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
private Object receivedObject;
private final Object mutex = new Object();
public static void main (String[] args) throws InterruptedException {
Object obj = new Test2().someMethod();
System.out.println("The object is" + obj + ", wooh!");
executorService.shutdown();
}
public void callObject() {
System.out.println("callObject ...");
// Sends request for the object asynchronously!
executorService.submit(() -> {
// some wait time to simulate slow request
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// provide object to callback
receiveObject(UUID.randomUUID().toString());
});
System.out.println("callObject done.");
}
public void receiveObject(Object object) {
System.out.println("receiveObject ...");
synchronized (mutex) {
this.receivedObject = object;
mutex.notify();
}
System.out.println("receiveObject done.");
}
public Object someMethod() throws InterruptedException {
System.out.println("someMethod ...");
synchronized (mutex) {
callObject();
while(this.receivedObject == null){
mutex.wait();
}
}
System.out.println("someMethod done.");
return this.receivedObject;
}
}
someMethod
wartet, bis receivedObject
existiert. receiveObject
benachrichtigt bei Ankunft.
Es ist ein guter Ausgangspunkt, aber ich bin nicht sicher, wie das Empfangsverfahren die someLongAsyncOperation mit seinem Ergebnis liefern würde? – Anonomoose
Das klingt so, als ob 'receiveObject' aufgerufen werden soll, wenn der Vorgang beendet ist. Das ist eher ein Rückruf als eine Zukunft.Lassen Sie mich versuchen, ein Beispiel zu geben ... –
Ja, das ist, was ich vorhabe - Entschuldigung! – Anonomoose