Future
Interface introduite dans Java 5. Utilisé pour modéliser les résultats futurs qui pourraient être disponibles à un moment donné. Modélisez le traitement asynchrone et fournissez une référence au résultat lorsque le traitement est terminé. Future permet au thread appelant de continuer un autre processus au lieu d'attendre le résultat. Java8 In Action
Enveloppez le processus chronophage dans l'objet Callable
et passez-le à ExecutorSerice.
ExecutorService executor = Executors.newCachedThreadPool();
//Passer des tâches au pool de threads
Future<Double> future = executor.submit(new Callable<Double>() {
public Double call() { //Effectuer le traitement dans un autre thread
return doSomeLongComputation();
}});
doSomethingElse();
Utilisez la méthode get de Future pour obtenir le résultat du traitement asynchrone. En utilisation réelle, vous devez intercepter plusieurs exceptions. Future.get
Double value = future.get();
Double result = future.get(1, TimeUnit.SECONDS); //Spécifiez le délai d'expiration
doSomeLongComputation
ne renvoie jamais de résultat"En utilisant la méthode suivante Vous pouvez être sûr que le processus asynchrone est terminé
Puis
doSomeLongComputation
est utilisé par un autre FuturedoSomeMoreLongComputation
"Que devrais-je faire?
Le point déroutant est qu'il existe un ordre d'exécution entre les processus asynchrones.
En exécutant le deuxième futur
Il est nécessaire de vérifier activement le résultat du premier futurdoSomeLongComputation
. </ del>
ExecutorService executor = Executors.newCachedThreadPool();
Future<Double> future = executor.submit(new Callable<Double>() {
public Double call() {
return doSomeLongComputation();
}});
//Surveiller jusqu'à ce que le traitement du premier futur soit terminé
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;
}
}});
Il est possible d'écrire un processus qui a un ordre entre les processus asynchrones sans utiliser l'instruction while.
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));
//1er avenir
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));
//Deuxième avenir
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(); //Appelez le premier futur
System.out.println(String.format("after future.get elapsed time: %d msecs", (System.nanoTime()-start)/1_000_000));
//Utilisez le résultat du traitement du premier futur
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));
//Appelez le deuxième avenir ici
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);
}
résultat Le traitement du second futur est bloqué jusqu'à ce que le traitement du futur imbriqué soit terminé (∵ Le deuxième futur utilise le résultat du traitement du premier futur).
before future elapsed time: 3 msecs
doSomeLongComputation called
after future elapsed time: 25 msecs
before futureSecond.get elapsed time: 26 msecs <-Commencer le deuxième avenir
before future.get elapsed time: 26 msecs <-Début du premier futur imbriqué
doSomeLongComputation: 10
after future.get elapsed time: 10027 msecs <-Fin du premier futur imbriqué
doSomeLongMoreComputation called
doSomeLongMoreComputation: 11
after futureSecond.get elapsed time: 20029 msecs <-Fin du deuxième avenir
Ce que je veux réaliser à la fin, c'est ...
celles-ci,
En utilisant les fonctionnalités de ** Java8 **,
Utilisez CompletableFuture
si vous voulez le faire de manière déclarative.
Recommended Posts