Los grupos de hilos pueden ejecutar múltiples tareas simultáneamente. A veces, es posible que deseemos rastrear los resultados de ejecución de las tareas. Incluso dentro de un cierto período de tiempo, si la tarea no se completa, también es posible que deseemos cancelar la ejecución de tareas. Para admitir esta función, ThreadPoolExecutor proporciona FutUreTask para rastrear la ejecución y cancelación de tareas. Este artículo presenta el principio de implementación de Futuretask.
Para comprender mejor el principio de implementación de FutureTask, primero proporcionamos varias interfaces y estructuras de clase importantes, como se muestra en la figura a continuación:
ThreadPoolExecutor proporciona la interfaz de envío para enviar tareas. Enviar admite dos interfaces diferentes: ejecutables y llamables. Para proporcionar una interfaz externa unificada, JDK envuelve internamente en un llamable, todo lo cual se implementa a través del adaptador RunNableAdapter. El siguiente es el código fuente de runnableAdapter:
Clase final estática runnableAdapter <t> implementa la tarea llamable <t> {final runnable; resultado T final; RunnableAdapter (tarea runnable, t resultado) {this.task = tarea; this.result = resultado; } public t call () {task.run (); resultado de retorno; }}RunnableAdapter es la clase de implementación de llamadas, que implementa el método de llamada. El método de llamada simplemente llama a tarea.run () y luego devuelve el resultado, lo que asegura que solo la interfaz invocable debe manejarse de manera uniforme internamente.
A través de la sección anterior, sabemos que la tarea ejecutable enviada se convierte internamente en tareas invocables. Verifique el valor de retorno del método de envío, que es un futuro. De hecho, este futuro es una instancia de FuturetAk. A través de esta instancia, llamar al método GET puede bloquear el hilo actual hasta que se complete la tarea y se devuelve el resultado.
Toda la cadena de llamadas se ve así:
Worker Thread -> futuretask.run () -> callable.call () -> task.run ()
Si se envía la tarea invocable, solo hay las tres primeras llamadas.
Para demostrar mejor todo el proceso, los siguientes ejemplos se utilizarán para demostrar el proceso de ejecución.
1. Envíe una tarea llamable al grupo de subprocesos (Runnable también se convertirá en llamadas). En este momento, el llamable se pasa a una instancia de FuturetAk, como se muestra a continuación:
2. El grupo de subprocesos usa un hilo para ejecutar la tarea de FutureTask.
El proceso de ejecución de tareas es relativamente simple. Al final, se llamará al método Callable.Call () o Runnable.run (), y se obtendrá un resultado, que almacenará el resultado en la propiedad de resultado de la instancia de FuturetAk, y el estado se modificará a la normalidad, lo que indica que la tarea se ha ejecutado y se puede obtener el resultado.
Suponemos que múltiples hilos llaman al método GET de la misma instancia de FuturetAk durante la ejecución de callable.call() . En este momento, estos hilos serán bloqueados y almacenados en una pila, como se muestra en la figura a continuación:
Los hilos 1, 2 y 3 llaman FutureTask.get . Dado que la tarea no se ha ejecutado, los tres hilos serán bloqueados y con sueño. Hay una pila en Futuretask para almacenar hilos que esperan. El puntero superior de la pila es referenciado por FutureTask.waiters . Cuando se ejecuta la tarea, los hilos en toda la pila iterarán. En este momento, cada hilo se despertará y el resultado de la ejecución de la tarea se puede obtener con éxito (el resultado de la ejecución se almacena en FutureTask.outcome) .
FutureTask también admite la función de cancelación de las tareas, todos los cuales coordinan múltiples hilos a través del estado de FuturetAk.
La interfaz FutureTask es un mecanismo de implementación que nos proporciona el seguimiento y el control de la ejecución de tareas. En comparación con el grupo de hilos, es relativamente simple y creo que no es difícil de entender.
Lo anterior es todo el contenido de este artículo sobre el principio de implementación de Futuretask en Java Thread Pool. Espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!