Un hilo es un único flujo de ejecución dentro de un proceso. Pero será mejor comenzar desde el principio y explicar qué es un proceso.
Un hilo es una secuencia de código en ejecución dentro del contexto de un proceso. Los hilos no pueden ejecutarse ellos solos; requieren la supervisión de un proceso padre para correr.
Dentro de cada proceso hay varios hilos ejecutándose. Por ejemplo, Word puede tener un hilo en background chequeando automáticamente la gramática de lo que estoy escribiendo, mientras otro hilo puede estar salvando automáticamente los cambios del documento en el que estoy trabajando. Como Word, cada aplicación (proceso) puede correr varios hilos los cuales están realizando diferentes tareas. Esto significa que los hilos están siempre asociados con un proceso en particular
.
Los hilos a menudo son conocidos o llamados procesos ligeros. Un hilo, en efecto, es muy similar a un proceso pero con la diferencia de que un hilo siempre corre dentro del contexto de otro programa. Por el contrario, los procesos mantienen su propio espacio de direcciones y entorno de operaciones. Los hilos dependen de un programa padre en lo que se refiere a recursos de ejecución. La siguiente figura muestra le relación entre hilos y procesos.
CICLO DE VIDA DE UN HILO
CICLO DE VIDA DE UN THREADS
• Quantum es la cuota de tiempo en que un Thread está en la CPU. Los Threads se intercambian entre sí mediante un algoritmo circular ("round-robin")
• La operación de dispatch consiste en seleccionar un proceso para que sea él el que entre en ejecución.
• suspend y resume son metodos de Thread.
• Cuando se realiza una petición de operación de I/O el Thread queda bloqueado hasta que termine la operación.
• El mecanismo de wait, notify y notifyAll se utiliza para coordinar el sincronismo cuando varios Threads intentan acceder simultáneamente a un recurso (objeto) común.
• El thread en ejecución incluso el correspondiente al programa principal (main) se puede obtener con el método estático currentThread() de la clase Thread.
• Con ello se podría detener la ejecución del hilo un tiempo determinado:
...
Thread.currentThread().sleep(2000); // el programa se detiene durante 2 segundos
...
Clases Relacionadas con los Hilos
El lenguaje de programación Java proporciona soporte para hilos a través de una simple interfaz
y un conjunto de clases. La interfaz de Java y las clases que incluyen funcionalidades sobre hilos son las siguientes:
• Thread
• Runnable
• ThreadDeath
• ThreadGroup
• Object
Todas estas clases son parte del paquete Java.lang.
Thread
La clase Thread es la clase responsable de producir hilos funcionales para otras clases. Para
añadir la funcionalidad de hilo a una clase simplemente se deriva la clase de Thread y se ignora el método run. Es en este método run donde el procesamiento de un hilo toma lugar, y a menudo se refieren a él como el cuerpo del hilo. La clase Thread también define los métodos start y stop, los cuales te permiten comenzar y parar la ejecución del hilo, además de un gran número de métodos útiles.
Runnable(CLASE INTERFAZ)
Java no soporta herencia múltiple de forma directa, es decir, no se puede derivar una clase de varias clases padre. Esto nos plantea la duda sobre cómo podemos añadir la funcionalidad de
Hilo a una clase que deriva de otra clase, siendo ésta distinta de Thread. Para lograr esto se utiliza la interfaz Runnable. La interfaz Runnable proporciona la capacidad de añadir la funcionalidad de un hilo a una clase simplemente implementando la interfaz, en lugar de derivándola de la clase Thread.
Las clases que implementan la interfaz Runnable proporcionan un método run que es ejecutado por un objeto hilo asociado que es creado aparte. Esta es una herramienta muy útil y a menudo es la única salida que tenemos para incorporar multihilo dentro de las clases. Esta cuestión será tratada más ampliamente en el apartado de Creación de hilos.
ThreadDeath
La clase de error ThreadDeath proporciona un mecanismo que permite hacer limpieza después de que un hilo haya sido finalizado de forma asíncrona. Se llama a ThreadDeath una clase error porque deriva de la clase Error, la cual proporciona medios para manejar y notificar errores. Cuando el método stop de un hilo es invocado, una instancia de ThreadDeath es lanzada por el moribundo hilo como un error. Sólo se debe recoger el objeto ThreadDeath si se necesita para realiza una limpieza específica a la terminación asíncrona , lo cual es una situación bastante inusual. Si se recoge el objeto, debe ser relanzado para que el hilo realmente muera.
ThreadGroup
La clase ThreadGroup se utiliza para manejar un grupo de hilos de modo conjunto. Esto nos proporciona un medio para controlar de modo eficiente la ejecución de una serie de hilos. Por ejemplo la clase ThreadGroup nos proporciona métodos stop, suspend y resume para controlar la ejecución de todos los hilos pertenecientes al grupo. Los grupos de hilos también pueden contener otros grupos de hilos permitiendo una jerarquía anidada de hilos. Los hilos individuales tienen acceso al grupo pero no al padre del grupo.
Object
Aunque, estrictamente hablando, no es una clase de apoyo a los hilos, la clase objeto proporciona unos cuantos métodos cruciales dentro de la arquitectura multihilo de Java. Estos métodos son wait, notify y notifyAll. El método wait hace que el hilo de ejecución espere en estado dormido hasta que se le notifique que continúe. Del mismo modo, el método notify informa a un hilo en espera de que continúe con su ejecución. El método notifyAll es similar a notify excepto que se aplica a todos los hilos en espera. Estos tres métodos solo pueden ser llamados desde un método o bloque sincronizado (o bloque de sincronización).
Normalmente estos métodos se utilizan cuando hay ejecución multihilo, es decir, cuando un
método espera a que otro método termine de hacer algo antes de poder continuar. El primer hilo espera hasta que otro hilo le notifique que puede continuar. La clase objeto está en la parte superior de la jerarquía de Java, lo cual significa que es el padre de todas las clases. En otras palabras, cada clase Java hereda la funcionalidad proporcionada por la clase objeto, incluyendo los métodos wait, notify y notifyAll.
Lo más habitual es crear hilos implementando la interfaz Runnable, dado que las interfaces representan una forma de encapsulamiento del trabajo que una clase debe realizar.
Así, se utilizan para el diseño de requisitos comunes a todas las clases que se tiene previsto implementar. La interfaz define el trabajo, la funcionalidad que debe cubrirse, mientras que la clase o clases que implementan la interfaz realizan dicho trabajo (cumplen esa funcionalidad).
Todas las clases o grupos de clases que implementen una cierta interfaz deberán seguir las mismas reglas de funcionamiento.
El otro mecanismo de creación de hilos, como ya hemos dicho, consistiría en la creación previa de una subclase de la clase Thread, la cual podríamos instanciar después.
Por ejemplo,
Class MiThread extends Thread {
Public void run() {
. . .
}
}
se corresponde con la declaración de un clase, MiThread, que extiende la clase Thread, sobrecargando el método Thread.run heredado con su propia implementación.
Es en el método run donde se implementa el código correspondiente a la acción (la tarea)
que el hilo debe desarrollar . El método run no es invocado directa o explícitamente (a menos
que no quieras que se ejecute dentro de su propio hilo). En lugar de esto, los hilos se arrancan
con el método start, se suspenden con el método suspend, se reanudan con el método
resume, y se detienen con el método stop (el cual supone también la muerte del hilo y la
correspondiente excepción ThreadDeath), como ya explicaremos en el apartado de Estado y
Control de Hilos. Un hilo suspendido puede reanudarse en la instrucción del método run en la que fue suspendido.
En el caso de crear un hilo extendiendo la clase Thread, se pueden heredar los métodos y variables de la clase padre. Si es así, una misma subclase solamente puede extender o derivar una vez de la clase padre Thread. Esta limitación de Java puede ser superada a través de la implementación de Runnable. Veamos el siguiente ejemplo:
Public class MiThread implements Runnable {
Thread t;
Public void run () {
// Ejecución del thread una vez creado
}
}
En este caso necesitamos crear una instancia de Thread antes de que el sistema pueda ejecutar el proceso como un hilo. Además, el método abstracto run que está definido en la interfaz Runnable tiene que implementarse en la nueva clase creada.
DIFERENCIAS EN LOS MÉTODOS DE LA CREACIÓN DE HILOS
La diferencia entre ambos métodos de creación de hilos en Java radica en la flexibilidad con que cuenta el programador, que es mayor en el caso de la utilización de la interfaz Runnable.
Sobre la base del ejemplo anterior, se podría extender la clase MiThread a continuación, si fuese necesario. La mayoría de las clases creadas que necesiten ejecutarse como un hilo implementarán la interfaz Runnable, ya que así queda cubierta la posibilidad de que sean extendidas por otras clases.
Métodos en Hilos
Put ()
Get ()
Run ()
Start ()
Yield ()
Wait ()
Sleep ()
Synchronized ()
stop()
resume()
notifyAll()
notify()
isAlive() : Para saber si el thread esta vivo.
No hay comentarios:
Publicar un comentario