[JAVA] Abschließende Zukunft Erste Schritte (Erste Zukunft)

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

Was mich glücklich macht, Future zu nutzen

  1. Kein Warten mehr auf zeitaufwändige Bearbeitung
  2. Einfacher zu verarbeiten als Fäden mit niedriger Schicht

wie benutzt man

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

Dinge, die bei der asynchronen Verarbeitung mit Future zu beachten sind

"Wenn der umschlossene Prozess" doSomeLongComputation "niemals ein Ergebnis zurückgibt"

Mit der folgenden Methode Sie können sicher sein, ob der asynchrone Prozess abgeschlossen ist

Dann

"Wenn das Ergebnis von FuturedoSomeLongComputation 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 ...

  1. Kombinieren Sie zwei asynchrone Prozesse
  2. Warten Sie, bis die gesamte vom Future-Block ausgeführte Verarbeitung abgeschlossen ist
  3. Warten Sie, bis nur die früheste ausgeführte Aufgabe im zukünftigen Block abgeschlossen ist
  4. Schließen Sie die Zukunft programmatisch ab
  5. Reagieren Sie auf den Abschluss von Future
  6. Benachrichtigen, wenn die Verarbeitung abgeschlossen ist
  7. Führen Sie die Verarbeitung mit zukünftigen Ergebnissen aus, anstatt auf die Verarbeitung der Ergebnisse zu warten

diese, Verwenden der Funktionen von ** Java8 **, Verwenden Sie "CompletableFuture", wenn Sie dies deklarativ tun möchten.

Recommended Posts

Abschließende Zukunft Erste Schritte (Erste Zukunft)
Erste Schritte mit Ruby
Java 8 Completable Future Survey
Erste Schritte mit Doma-Transaktionen
Erste Schritte mit der Verarbeitung von Doma-Annotationen
Erste Schritte mit Java Collection
Erste Schritte mit Java Basics
Erste Schritte mit Spring Boot
Erste Schritte mit Ruby-Modulen
Erste Schritte mit Java_Kapitel 5_Praktische Übungen 5_4
[Google Cloud] Erste Schritte mit Docker
Erste Schritte mit Docker mit VS-Code
CompletableFuture Erste Schritte 2 (Versuchen Sie, CompletableFuture zu erstellen)