En una aplicación única, cuando llame a un método, el resultado se devolverá solo cuando termine el cálculo.
Public String downloadContents (url url) lanza ioexception {trystream input = url.openStream ()) {return iOutils.tring (input, standardc harsets.utf_8);}} // ... Future final <strong> contents = descarga (nueva url ("http://www.example.com");
DownloadContents () parece inofensivo, pero debe hacerse durante mucho tiempo. Al mismo tiempo, para reducir el retraso, durante el resultado de espera, es posible que deba manejar otro trabajo de forma independiente al mismo tiempo. En el pasado, puede iniciar un nuevo hilo o esperar los resultados (compartir memoria, bloquear, Bad Wait ()/Notify () Par).
A través del modo <t> futuro, quedará claro:
Public static Future <String> startDownloading (url url) {// ...} Future final <string> contentsFuture = startDownload (nuevo, http: //www.example .com "))); // OTRO COMPUTATIONFinal String Contents = ContentsFuture .conseguir ();
Nos daremos cuenta de StartDownloading (), StartDownloading () no se bloqueará, pero esperando que los sitios externos respondan. Por el contrario, si devuelve rápidamente y devuelve un objeto <string> futuro ligero. Este objeto es una promesa, por lo que el tipo de cadena futura está disponible. En otras palabras, el futuro es un agente o un empaque de objetos, no un objeto objetivo real. Una vez que se completa el cálculo asincrónico, puede extraerlo. Entonces, ¿qué tipo de interfaz proporciona Future?
Future.get () es el método más importante. Bloquea y espera hasta que el resultado de la promesa esté disponible, por lo que si realmente necesitamos esta cadena, llame al método get () y espere. También hay una versión de carga pesada que acepta los parámetros de tiempo de espera.
En algunos casos, es posible que desee ver en secreto si el futuro está disponible. Esto se puede hacer a través de ISDone (). Imagine una situación, su usuario está esperando algunos cálculos asíncronos.
Future final <String> contentsFuture = startDownloading (new Url ("http://www.example.com"); while (! ContentsFuture.isDone ()) {askUserTowail (); do somecomputationIntheMeanTime ();} contentsfuture.get () () ;;
Finalmente, se garantiza que el contenido de Future.get () regrese inmediatamente sin ser bloqueado, porque Future.isDone () devuelve verdadero. Si sigue este modelo, no estará ocupado esperando y llamando a ISDone () alternativamente cada segundo.
Cancelar futrues es el último que no hemos cubierto. Imagine que comienza el trabajo asíncrono y solo puede esperar algún tiempo. Sin embargo, eres un buen ciudadano, debes decir este objeto futuro: ya no te necesito, no te importa. Luego puede ahorrar recursos deteniendo tareas obsoletas. La gramática es simple:
Contentsfuture.cancel (verdadero);
A todos nos gusta esconder los parámetros de tipo boer, ¿verdad? La cancelación se puede implementar de dos maneras: antes de que comience la tarea, se cancela el parámetro falso, siempre que antes de que se expresara los resultados del futuro, se inicia el cálculo. Una vez llamable.call () se está ejecutando a la mitad, entonces queremos dejarlo terminar. ¿Crees que esto es bueno? Fenómenos Aquellos que arrojan InterruptedException, el método infame, como Thread.sleep (), Object.Wait (), Conition.Await (), etc., incluso si está bloqueado en este método y algunas personas deciden cancelar su llamada Sin duda lanzarán la concepción de interrupción y enviarán a alguien para interrumpir la tarea de la operación actual.
Así que ahora entendemos qué es el futuro: un marcador de posición, puede obtener el objeto objetivo en el futuro. Al igual que un automóvil, no hay clave para la fabricación. Pero, ¿cómo puede obtener una instancia de futuro en la aplicación? Los dos recursos más comunes son los grupos de subprocesos y los métodos asincrónicos (soporte del grupo de subprocesos). Por lo tanto, el método startDownloading () se puede reescribir como:
Private Final ExecutorService Pool = Ejecutors.NewFixedThreadPool (10); InputStream input = url.openStream ()) {return ioutils.toString (input, StandardCharSets.utf_8);}});}
Aunque hay muchos problemas de gramática tediosos, el pensamiento básico es simple: la computación de empaque que debe ejecutarse durante mucho tiempo está empaquetada al ajuste <String> y enviar () al grupo de hilos. trapos. Después de enviar, la implementación de Future <String> es como vincular a su tarea y grupo de hilos de alguna manera. Obviamente, su tarea no se ejecutará de inmediato. La tarea de permanecer en el medio también puede cancelar la tarea que se ha estado ejecutando durante mucho tiempo, pero esto es algo más complicado.
También puedes conocer a Future en Spring y EJB. Por ejemplo, puede agregar la anotación de @async al marco de primavera:
@AsyncPublic Future <String> startDownloading (URL Final URL) lanza IOException {try (inputStream input = url.openStream ()) {return New Asyncres Ult <> (ioutils.ToString (input, StandardCharsets.utf_8));}}
Tenga en cuenta que simplemente implementamos el futuro a través del resultado del empaque a Asyncresult, pero este método en sí no interactuará con el grupo de subprocesos o asíncrono procesado. Spring más tarde representará todas las llamadas a StartDownloading () y ejecutará en el grupo de subprocesos. En EJB, la misma característica se completa agregando @asynchronousannotation.