Future
In Java 5 eingeführte Schnittstelle. Wird verwendet, um zukünftige Ergebnisse zu modellieren, die möglicherweise irgendwann verfügbar sind. Modellieren Sie die asynchrone Verarbeitung und geben Sie nach Abschluss der Verarbeitung einen Verweis auf das Ergebnis an. Future ermöglicht es dem aufrufenden Thread, einen anderen Prozess fortzusetzen, anstatt auf das Ergebnis zu warten. Java8 In Action
Wickeln Sie den zeitaufwändigen Prozess in das Objekt "Callable" ein und übergeben Sie ihn an ExecutorSerice.
ExecutorService executor = Executors.newCachedThreadPool();
//Übergeben Sie Aufgaben an den Thread-Pool
Future<Double> future = executor.submit(new Callable<Double>() {
public Double call() { //Führen Sie die Verarbeitung in einem anderen Thread durch
return doSomeLongComputation();
}});
doSomethingElse();
Verwenden Sie die get-Methode von Future, um das Ergebnis der asynchronen Verarbeitung abzurufen. Bei der tatsächlichen Verwendung müssen Sie mehrere Ausnahmen abfangen. Future.get
Double value = future.get();
Double result = future.get(1, TimeUnit.SECONDS); //Geben Sie die Zeitüberschreitungszeit an
Mit der folgenden Methode Sie können sicher sein, ob der asynchrone Prozess abgeschlossen ist
Dann
doSomeLongComputation
von einem anderen FuturedoSomeMoreLongComputation
verwendet wird" "Was soll ich machen?
Der verwirrende Punkt ist, dass es eine Ausführungsreihenfolge zwischen asynchronen Prozessen gibt.
Bei der Ausführung der zweiten Zukunft
Es ist notwendig, das Ergebnis der ersten zukünftigen "doSomeLongComputation" aktiv zu überprüfen. </ del>
ExecutorService executor = Executors.newCachedThreadPool();
Future<Double> future = executor.submit(new Callable<Double>() {
public Double call() {
return doSomeLongComputation();
}});
//Überwachen Sie, bis die Verarbeitung der ersten Zukunft abgeschlossen ist
do {
System.out.println("in while");
} while(!future.isDone());
Future<Double> futureSecond = executor.submit(new Callable<Double>() {
public Double call() {
try {
return doSomeLongMoreComputation(future.get());
} catch (InterruptedException | ExecutionException e) {
return 0.0;
}
}});
Es ist möglich, einen Prozess mit einer Reihenfolge zwischen asynchronen Prozessen zu schreiben, ohne die while-Anweisung zu verwenden.
long start = System.nanoTime();
ExecutorService executor = Executors.newCachedThreadPool();
System.out.println(String.format("before future elapsed time: %d msecs", (System.nanoTime()-start)/1_000_000));
//1. Zukunft
Future<Double> future = executor.submit(new Callable<Double>() {
public Double call() {
return doSomeLongComputation();
}});
System.out.println(String.format("after future elapsed time: %d msecs", (System.nanoTime()-start)/1_000_000));
//Zweite Zukunft
Future<Double> futureSecond = executor.submit(new Callable<Double>() {
public Double call() {
try {
System.out.println(String.format("before future.get elapsed time: %d msecs", (System.nanoTime()-start)/1_000_000));
double value = future.get(); //Nennen Sie die erste Zukunft
System.out.println(String.format("after future.get elapsed time: %d msecs", (System.nanoTime()-start)/1_000_000));
//Verwenden Sie das Verarbeitungsergebnis der ersten Zukunft
return doSomeLongMoreComputation(value);
} catch (InterruptedException | ExecutionException e) {
return 0.0;
}
}});
try {
System.out.println(String.format("before futureSecond.get elapsed time: %d msecs", (System.nanoTime()-start)/1_000_000));
//Nennen Sie hier die zweite Zukunft
double d = futureSecond.get();
System.out.println(String.format("after futureSecond.get elapsed time: %d msecs", (System.nanoTime()-start)/1_000_000));
} catch (InterruptedException | ExecutionException e) {
System.out.println(e);
}
Ergebnis Die Verarbeitung der zweiten Zukunft wird blockiert, bis die Verarbeitung der verschachtelten Zukunft abgeschlossen ist (∵ Die zweite Zukunft verwendet das Verarbeitungsergebnis der ersten Zukunft).
before future elapsed time: 3 msecs
doSomeLongComputation called
after future elapsed time: 25 msecs
before futureSecond.get elapsed time: 26 msecs <-Starten Sie die zweite Zukunft
before future.get elapsed time: 26 msecs <-Beginn der ersten verschachtelten Zukunft
doSomeLongComputation: 10
after future.get elapsed time: 10027 msecs <-Ende der ersten verschachtelten Zukunft
doSomeLongMoreComputation called
doSomeLongMoreComputation: 11
after futureSecond.get elapsed time: 20029 msecs <-Ende der zweiten Zukunft
Was ich am Ende erreichen möchte, ist ...
diese, Verwenden der Funktionen von ** Java8 **, Verwenden Sie "CompletableFuture", wenn Sie dies deklarativ tun möchten.
Recommended Posts