Java a une classe Thread depuis le début, mais l'instanciation était lourde et subtile.
Executor a été introduit à partir de JDK5, ce qui facilite les opérations de type WorkerThread, et le nombre de classes de type Lock a augmenté, ce qui le rend plus pratique. De plus, l'introduction de Future a facilité la réception des résultats du traitement. Cependant, lorsque vous appelez Future.get (), l'appel Thread se bloque, vous devez donc écrire quelque chose qui n'est pas essentiel, comme le faire avec un autre Thread.
Completable Future a été introduit à partir de Java8, et il semble qu'un traitement Thread plus compliqué puisse être effectué, je vais donc l'examiner.
Si vous ne comprenez pas la fonction, le consommateur et le fournisseur, qui ont également été introduits dans Java 8, vous ne comprendrez pas. J'ai écrit un article ci-dessous, alors veuillez vous y référer. Enquête sur la fonction Java 8, consommateur, fournisseur, prédicat
Puisque c'est le fournisseur qui renvoie une certaine valeur et le consommateur qui reçoit et traite la valeur, combinez les deux.
CompletableFuture.supplyAsync (Supplier) renvoie une instance de CompletableFuture lors du traitement asynchrone du fournisseur. Avec CompletableFuture.thenAcceptAsync (Consumer), lorsque le traitement de l'instance CompletableFuture est terminé, transmettez la valeur de retour et exécutez le traitement Consumer.
public void SupplyAndConsume() {
Supplier<Integer> initValueSupplier = () -> 100;
Consumer<Integer> valueConsumer = value -> System.out.println(value);
CompletableFuture<Void> future =
CompletableFuture.supplyAsync(initValueSupplier)
.thenAcceptAsync(valueConsumer);
}
Résultat du traitement
100
C'est le fournisseur qui renvoie une certaine valeur, la fonction qui la convertit et le consommateur qui la reçoit et la traite.
Fondamentalement identique au modèle précédent, mais avec CompletableFuture.thenApplyAsync (Function), exécutez le traitement Function en passant la valeur du résultat de CompletableFuture.
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);
}
Résultat du traitement
200
Renvoie le résultat traité par le fournisseur et traite en utilisant la valeur reçue par le consommateur. CompletableFuture.acceptEitherAsync (CompletableFuture, Consumer) peut être utilisé pour effectuer le traitement Consumer en utilisant celui qui donne le résultat en premier.
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
Explication de l'exemple d'erreur synchronisée et typique J'ai écrit, alors vérifiez-le également. Empiriquement, environ 70% des gens ont tort.