Java hat von Anfang an eine Thread-Klasse, aber die Instanziierung war schwer und subtil.
Executor wurde aus JDK5 eingeführt, um WorkerThread-ähnliche Aufgaben zu vereinfachen, und die Anzahl der Klassen vom Typ Lock hat zugenommen, was die Arbeit erleichtert. Darüber hinaus hat die Einführung von Future den Erhalt von Verarbeitungsergebnissen erleichtert. Wenn Sie jedoch Future.get () aufrufen, wird der Aufruf von Thread blockiert, sodass Sie etwas schreiben müssen, das nicht unbedingt erforderlich ist, z. B. mit einem anderen Thread.
Completable Future wurde aus Java8 eingeführt, und es scheint, dass eine kompliziertere Thread-Verarbeitung durchgeführt werden kann, daher werde ich dies untersuchen.
Wenn Sie Function, Consumer und Supplier, die ebenfalls in Java 8 eingeführt wurden, nicht verstehen, werden Sie es nicht verstehen. Ich habe unten einen Artikel geschrieben, bitte beziehen Sie sich darauf. Untersuchung der Java 8-Funktion, des Verbrauchers, des Lieferanten, des Prädikats
Da der Lieferant einen bestimmten Wert zurückgibt und der Verbraucher den Wert empfängt und verarbeitet, kombinieren Sie beide.
CompletableFuture.supplyAsync (Lieferant) gibt eine Instanz von CompletableFuture zurück, während der Lieferant asynchron verarbeitet wird.
public void SupplyAndConsume() {
Supplier<Integer> initValueSupplier = () -> 100;
Consumer<Integer> valueConsumer = value -> System.out.println(value);
CompletableFuture<Void> future =
CompletableFuture.supplyAsync(initValueSupplier)
.thenAcceptAsync(valueConsumer);
}
100
public void SupplyAndExecuteAndConsume() {
Supplier<Integer> initValueSupplier = () -> 100;
Function<Integer, Integer> multiply = value -> value * 2;
Consumer<Integer> valueConsumer = value -> System.out.println(value);
CompletableFuture<Void> future =
CompletableFuture.supplyAsync(initValueSupplier)
.thenApplyAsync(multiply)
.thenAcceptAsync(valueConsumer);
}
200
Gibt das vom Lieferanten verarbeitete Ergebnis zurück und verarbeitet es mit dem vom Verbraucher empfangenen Wert. CompletableFuture.acceptEitherAsync (CompletableFuture, Consumer) kann verwendet werden, um die Consumer-Verarbeitung unter Verwendung derjenigen durchzuführen, die zuerst das Ergebnis liefert.
public void RaceAndConsume() {
Supplier<Integer> initValueSupplier = () -> 100;
Supplier<Integer> anotherValueSupplier = () -> 200;
Consumer<Integer> valueConsumer = value -> System.out.println(value);
CompletableFuture<Integer> future1 =
CompletableFuture.supplyAsync(initValueSupplier);
CompletableFuture<Integer> future2 =
CompletableFuture.supplyAsync(anotherValueSupplier);
future1.acceptEitherAsync(future2, valueConsumer);
}
100 or 200
public void RaceAndConsume() {
Supplier<Integer> initValueSupplier = () -> 100;
Supplier<Integer> anotherValueSupplier = () -> 200;
Function<Integer, Integer> multiply = value -> value * 2;
Consumer<Integer> valueConsumer = value -> System.out.println(value);
CompletableFuture<Integer> future1 =
CompletableFuture.supplyAsync(initValueSupplier);
CompletableFuture<Integer> future2 =
CompletableFuture.supplyAsync(anotherValueSupplier);
future1.applyToEitherAsync(future2, multiply)
.thenAcceptAsync(valueConsumer);
}
200 or 400
Erläuterung des synchronisierten und typischen Fehlerbeispiels Ich habe geschrieben, also schau es dir bitte auch an. Empirisch sind etwa 70% der Menschen falsch.