Dans une application unique, lorsque vous appelez une méthode, le résultat ne sera retourné que lorsque le calcul est terminé.
Public String DownloadContents (URL URL) lève IOException {TryStream Input = url.openStream ()) {return ioutils.tring (entrée, standardc harsets.utf_8);}} // ... Final Future <strong> contente = DownloadContents (new URL ("http://www.example.com");
DownloadContents () semble inoffensif, mais cela doit être fait pendant longtemps. Dans le même temps, afin de réduire le retard, pendant le résultat d'attente, vous devrez peut-être gérer les autres travaux de manière indépendante en même temps. Dans le passé, vous pouvez démarrer un nouveau thread ou attendre les résultats (partage de mémoire, verrouillage, bad wait () / notify () paire).
À travers le mode futur <T>, il deviendra clair:
Public Static Future <string> startDownloading (URL URL) {// ...} Final Future <string> ContentsFuture = startdownload (new, http: //www.example .com ")); // autre calculat de la chaîne contente = contenufuture .obtenir ();
Nous réaliserons que StartDownloading (), StartDownloading () ne sera pas bloqué, mais en attendant que les sites externes répondent. Au contraire, s'il revient rapidement et renvoie un objet <string> léger Future <string>. Cet objet est une promesse, donc le type de chaîne future est disponible. En d'autres termes, l'avenir est un agent ou un emballage d'objet, pas un véritable objet cible. Une fois le calcul asynchrone terminé, vous pouvez l'extraire. Alors, quel type d'interface provient l'avenir?
Future.get () est la méthode la plus importante. Il bloque et attendez que le résultat de la promesse soit disponible, donc si nous avons vraiment besoin de cette chaîne, appelez la méthode get () et attendez. Il existe également une version lourde qui accepte les paramètres de délai d'expiration.
Dans certains cas, vous voudrez peut-être voir secrètement si l'avenir est disponible. Cela peut être fait via Isdone (). Imaginez une situation, votre utilisateur attend des calculs asynchrones.
Final Future <string> contentefuture = startDownloading (new URL ("http://www.example.com"); while (! Contentesfuture.isdone ()) {AskUsertowail (); do SomeCutationIntheMeantime ();} ContestsFuture.get () ;;
Enfin, le contenu de Future.get () est garanti de revenir immédiatement sans être bloqué, car future.isdone () revient vrai. Si vous suivez ce modèle, vous ne serez pas occupé à attendre et à appeler Isdone () alternativement chaque seconde.
L'annulation de Futrues est la dernière que nous n'avons pas couverte. Imaginez que vous commencez le travail asynchrone et vous ne pouvez attendre que quelque temps. Cependant, vous êtes un bon citoyen, vous devriez dire ce futur objet: je n'ai plus besoin de vous, vous vous en souciez. Ensuite, vous pouvez économiser des ressources en arrêtant des tâches obsolètes. La grammaire est simple:
Contenufuture.cancel (true); // meh ...
Nous aimons tous nous cacher, les paramètres de type Boer, non? L'annulation peut être mise en œuvre de deux manières: avant le début de la tâche, le faux paramètre est annulé, à condition qu'avant les résultats du futur exprimé, le calcul commence. Une fois que Callable.Call () fonctionne à la moitié, nous voulons le laisser se terminer. Pensez-vous que c'est bien? Phénomènes ceux qui vomissent InterruptedException, la infâme méthode, comme Thread.Sleep (), Object.Wait (), Conition.Await (), etc., même si vous êtes bloqué dans cette méthode et certaines personnes décident d'annuler votre appel , ils enverront sans aucun doute la conception Interruption, et enverront quelqu'un pour interrompre la tâche du fonctionnement actuel.
Nous comprenons donc maintenant ce qu'est l'avenir --- un espace réservé, vous pouvez obtenir l'objet cible à l'avenir. Tout comme une voiture, il n'y a pas de clé à fabriquer. Mais comment pouvez-vous obtenir une instance d'avenir dans l'application? Les deux ressources les plus courantes sont les pools de threads et les méthodes asynchrones (prise en charge du pool de threads). Par conséquent, la méthode StartDownloading () peut être réécrite comme suit:
Private Final Executorvice pool = exécutor InputStream input = url.openStream ()) {return ioutils.tostring (entrée, standardCharsets.Utf_8);}});}
Bien qu'il y ait beaucoup de problèmes de grammaire fastidieux, la pensée de base est simple: l'informatique de l'emballage qui doit fonctionner pendant une longue période est emballée à la <string> réglable, et soumettre () au pool de threads. Threads. Après la soumission, l'implémentation de Future <string> est comme un lien vers votre tâche et votre pool de threads d'une manière ou d'une autre. De toute évidence, votre tâche ne sera pas exécutée immédiatement. La tâche de rester au milieu peut également annuler la tâche qui s'exécute depuis longtemps, mais c'est une chose plus compliquée.
Vous pouvez également rencontrer Future au printemps et EJB. Par exemple, vous pouvez ajouter l'annotation de @async au framework Spring:
@Asyncpublic future <string> startDownloading (url final URL) lève ioException {try (inputStream input = url.openStream ()) {return new asyncres ult <> (ioutils.tostring (input, standardcharsets.utf_8));}}}}
Notez que nous implémentons simplement l'avenir à travers le résultat de l'emballage à AsynCresult, mais cette méthode elle-même n'interagira pas avec le pool de threads ou les asynchrones traités. Spring plus tard représentera tous les appels vers StartDownloading () et exécutera dans le pool de threads. Dans EJB, la même fonctionnalité est terminée en ajoutant @asynchronousannotation.