IMPLEMENTACION DE LA INTERFAZ RUNNABLE


Por este método se debe implementar la interfaz Runnable para la cual se debe sobreescribir el método run(). Una instancia de la clase puede ser creada y pasarla como argumento cuando se cree Thread e iniciarla.

La interfaz Runnable debe ser implementada por cualquier clase cuyas instancias sean ejecutadas por un hilo. Dicha clase debe implementar el método run(). La implementación de la interface Runnable es la forma más habitual de crear tareas, ya que proporciona al desarrollador una forma para agrupar el trabajo de infraestructura de la clase. La interfaz establece el trabajo a realizar y la clase o clases que la implementan, indican como realizar ese trabajo. Se puede construir un hilo sobre cualquier objeto que implemente la interfaz Runnable. Para implementar esta interfaz, una clase sólo tiene que implementar el método run(). Dentro de run() se define el código que constituye el nuevo hilo. Despues de haberse creado una clase que implemente la interfaz Runnable se requiere crear un objeto del tipo Thread dentro de esa clase, usando cualquiera de los constructores de Thread.

LA CLASE THREAD


Un thread es un hilo de ejecución de un programa. La Maquina Virtual de Java (JVM) permite la ejecución de concurrente de múltiples hilos. En la clase Thread se encapsula todo el control necesario sobre los hilos de ejecución o tareas. Un objeto Thread se le puede entender como el panel de control sobre una tarea o hilo de ejecución. Dispone de métodos para controlar el comportamiento de las tareas, los cuales se tratarán más adelante. Los siguientes son los principales métodos de Thread:
   
static int activeCount(): Retorna el múmero de el hilo activo en el grupo de hilos.

void checkAccess(): Chequea si eel hilo que se esta ejecutando tiene permiso para modificar este hilo.

static Thread currentThread(): Retorna el objeto Thread que representa a la tarea que se está ejecutando.

void destroy(): Destruye la tarea actual.

String getName(): Retorna el nombre actual del hilo, asignado con
setName().

int getPriority(): Retorna un valor entre 1 y 10, correspondiente a la prioridad de la tarea en ejecución.

ThreadGroup getThreadGroup(): Retorna el grupo de hilo a que pertenece el hilo actual.

void interrupt():Interrumpe el hilo.

static boolean interrupted(): Chequea si el hilo actual se ha interrumpido.

boolean isAlive(): Chequea si el hilo esta vivo.

boolean isDaemon(): Chequea si el hilo es un hilo de servicio a otros.

boolean isInterrupted(): Chequea si el hilo ha sido interrumpido.

void join(): Espera a que el hilo se muera.

void join(long millis): Espera hasta millis milisegundos para que el hilo muera.

void run(): Constituye el cuerpo de una tarea o hilo. Es llamado por el método start(), despues que la tarea apropiada del sistema se haya inicializado. La tarea actual se detendrá cada vez que run() devuelva el control. Este es el único método de la interfaz Runnable.

void setDaemon(boolean on): Marca este hilo como un hilo de servi iusuario o hilo demonio.

void setName(String name): Permite asignarle a la tarea un nombre con el cual se la puede identificar.

void setPriority(int newPriority): Cambia la prioridad de la tarea, entre los valores 1 y 10.

static void sleep(long millis): Provoca que el intérprete de Java ponga la tarea a dormir durante un tiempo indicado en milisegundos, transcurrido dicho tiempo la tarea estará disponible para ejecución.

void start(): Le indica al interprete de Java que cree un contexto de ejecución de una tarea e inicie su ejecución. Acto seguido se invoca el método run() de esta tarea en el nuevo contexto de ejecución. Debe tenerse cuidado de llamar a start() no más de una vez para una tarea determinada.

String toString(): Retorna la cadena que representa el hilo, que incluye nombre, prioridad y grupo del hilo.

static void yield(): Hace que el interprete detenga temporalmente la ejecución del objeto del hilo y permita que el siguiente hilo disponible se ejecute. 

SINTAXIS PARA CREAR UN HILO


Crear un hilo en java es una tarea muy sencilla. Basta heredar de la clase Thread y definir el método run(). Luego se instancia esta clase y se llama al método start() para que arranque el hilo. Más o menos esto


public MiHilo extends Thread
{
public void run()
{
// Aquí el código pesado que tarda mucho
}
};
...
MiHilo elHilo = new MiHilo();
elHilo.start();
System.out.println("Yo sigo a lo mio");


Listo. Hemos creado una clase MiHilo que hereda de Thread y con un método run(). En el método run() pondremos el código que queremos que se ejecute en un hilo separado. Luego instanciamos el hilo con un new MiHilo() y lo arrancamos con elHilo.start(). El System.out que hay detrás se ejecutará inmediatamente después del start(), haya terminado o no el código del hilo.





CICLO DE VIDA DE UN HILO

Un hilo tiene un ciclo de vida que va desde su creación hsta su terminación. Durante su ciclo de vida cada uno de los hilos o tareas de una aplicación puede estar en diferentes estados, algunos de los cuales se indican a continuación:

• Nacido: Cuando se acaba de crear un hilo, se dice que está nacido, y continúa en ese estado hasta que se invoca el método start() del hilo. La siguiente sentencia crea un nuevo thread pero no lo arranca, por lo tanto deja el thread en el estado de nacido.

       Thread miHilo = new MiClaseThread();

Cuando un thread está en este estado, es sólo un objeto Thread vacío o nulo. No se han asignado recursos del sistema todavía para el thread. Así, cuando un thread está en este estado, lo único que se puede hacer es arrancarlo con start().

• Listo: Cuando se invoca el método start() del hilo, se dice que está en estado listo. El método se arranca con la siguiente instrucción, para el caso del hilo miHilo:

       miHilo.start();

• Ejecutable: cuando el método start() se ejecuta, crea los recursos del sistema necesarios para ejecutar el thread,programa el thread para ejecutarse, y llama al método run() del thread que se ejecuta en forma secuencial. En este punto el thread está en el estado ejecutable. Se denomina así puesto que todavía no ha empezado a ejecutarse.

• En ejecución: Un hilo en estado de listo de la más alta prioridad, pasa al estado de ejecución, cuando se le asignan los recursos de un procesador, o sea cuando inicia su ejecución. Aquí el thread está en ejecución.Cada hilo tiene su prioridad, hilos con alta prioridad se ejecutan preferencialmente sobre los hilos de baja prioridad.

• No ejecutable :Un hilo continúa la ejecución de su método run(), hasta que pasa al estado de no ejecutable originado cuando ocurre alguno de los siguientes cuatro eventos:

Se invoca a su método sleep().
Se invoca a su su método suspend().
El thread utiliza su método wait() para esperar una condición variable.
El thread está bloqueado durante una solicitud de entrada/salida.

Por ejemplo, en el siguiente fragmento de codigo se pone a dormir
miHilo durante 10 segundos (10.000 milisegundos):

Thread miHilo = new MiClaseThread();
miHilo.start();
try {
miHilo.sleep(10000);
} catch (InterruptedException e){
}

Durante los 10 segundos que miHilo está dormido, incluso si el proceso se vuelve disponible, miHilo no se ejecuta. Después de 10 segundos, miHilo se convierte en "Ejecutable" de nuevo y, si el procesador está disponible se ejecuta. Para cada entrada en el estado "No Ejecutable", existe una ruta de escape distinta y específica que devuelve el thread al estado "Ejecutable". Por ejemplo, si un thread ha sido puesto a dormir dutante un cierto número de milisegundos deben pasar esos milisegundos antes de volverse "Ejecutable" de nuevo.

La siguiente es una secuencia de las acciones a realizar para cada entrada en el estado "No Ejecutable":

Si se ha puesto a dormir un hilo, deben pasar el número de milisegundos especificados en sleep().

Si se ha suspendido un hilo, se debe llamar a su método resume().

Si un hilo está esperando una condición variable, siempre que el objeto propietario de la variable renuncie mediante notify() o notifyAll().

Si un hilo está bloqueado durante la I/O, cuando se complete la I/O.

• Muerto: Un hilo pasa al estado de muerto cuando se termina su método run(), o cuando se ha invocado su método stop(). En algún momento el sistema dispondrá entonces del hilo muerto. Un hilo puede morir de dos formas:

Muerte natural: se produce cuando su método run() sale normalmente. Por ejemplo, el bucle while en este método es un bucle que itera 100 veces y luego sale. Por tanto el hilo morirá naturalmente cuando se llegue al final de la iteración, es decir se termina su método run().

public void run() {
int i = 0;
while (i < 100) {
i++;
System.out.println("i = " + i);
 }
}

Por muerte provocada: en cualquier momento llamando a su método
stop(). El siguiente código crea y arranca miHilo luego lo pone a
dormir durante 10 segundos. Cuando el thread actual se despierta, se lo mata con miHilo.stop(). El método stop() lanza un objeto
ThreadDeath hacia al hilo a eliminar. El thread moririá cuando reciba realmente la excepción ThreadDeath.

Thread miHilo = new MiClaseThread();
miHilo.start();
try {
Thread.currentThread().sleep(10000);
} catch (InterruptedException e){
}miHilo.stop();

El método stop() provoca una terminación súbita del método run() del hilo. Si el método run() estuviera realizando cálculos sensibles, stop() podría dejar el programa en un estado inconsistente. Normalmente, no se debería llamar al método stop() pero si se debería proporcionar una terminación educada como la selección de una bandera que indique que el método run() debería salir. El método stop() se encuentra depreciado en la version JDK1.2.1.

• Bloqueado: un hilo se encuentra en el estado bloqueado cuando el hilo realiza una solicitud de entrada/salida. Cuando termina la entrada/salida que estaba esperando, un hilo bloqueado queda en el estado listo.



DEFINICION DE HILOS


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.




Los hilos representan uno de los recursos más importantes de los que dispone un programador para crear aplicaciones complejas donde puede ser conveniente, o incluso necesario, realizar varias tareas de manera simultánea. El mecanismo de hilos de proceso de Java es sencillo, potente y productivo. De hecho muchos de los estándares de la plataforma Java, como por ejemplo los applets o los servlets, emplean hilos de proceso para llevar cabo algunas tareas en paralelo.