Ir al contenido principal

Hilos en Java(Threads) parte 2

Retomando el artículo anterior...

- Un hilo en Java es:
+ Una instancia de la clase java.lang.Thread
+ Un proceso en ejecución

- En una aplicación Java, el hilo principal es el derivado de la clase main, al cual llamamos proceso o hilo main.

- Cuando se trata de hilos, muy pocas cosas está garantizadas.

- Los principales métodos a tomar en cuenta con el manejo de los hilos son: start(), yield(), sleep() y run().

Más info tras el salto...



- Toda la acción o trabajo sucede dentro del método run().

- Para definir e instanciar un nuevo Thread (hilo, proceso) existen 2 formas:
+ Extendiendo (o heredando) a la clase java.lang.Thread
+ Implementando la interfaz Runnable

- Siempre se necesita un objeto tipo Thread para realizar el trabajo, independientemente si extiendes la clase Thread o implementas Runnable.

- Puedes pasar una misma instancia de una clase que implementa Runnable a diversos objetos de tipo Thread.

Continuando con lo visto anteriormente, existen diversos tipos de constructores a partir de los cuales se puede crear un hilo, algunos de los más importantes son:

+ Thread()
+ Thread(objetoRunnable)
+ Thread(objetoRunnable, String nombre)
+ Thread(String nombre)

Una vez que creamos e instanciamos un objeto tipo Thread, se dice que el objeto está en un estado 'new' o 'nuevo', es decir, ya existe pero aún no ha empezado con su trabajo, no está 'vivo'. Una vez que mandamos llamar al método start(), el hilo es considerado vivo o alive y se le considera como un hilo o proceso muerto una vez que el método run() fue completado. Existe un método para saber si el hilo está vivo o en ejecución, el método isAlive().


Comenzando con el trabajo::

Hasta ahora sabemos cómo crear el objeto tipo Thread e instanciarlo y sabemos que debe de estar en un estado vivo para que realice su función, para ello se utiliza el método start().

hilo.start();

Se debe de llamar al método start() a través de una instancia de la clase Thread. Una vez que llamamos al método start() sucede lo siguiente:

+ Un nuevo proceso de ejecución comienza (con su propia pila de información).
+ El hilo o proceso cambia de estado nuevo o new a estado de ejecución o runnable.
+ Cuando el hilo tenga su turno de ejecutarse, el método run() del objeto al que refiere se ejecuta.

P. ej.

public class Hilos {

public static void main(String[] args){
System.out.println("Dentro de main...");
HiloNuevo hn = new HiloNuevo();
Thread nuevoHilo = new Thread(hn);
nuevoHilo.start();
}
}

class HiloNuevo implements Runnable{

public HiloNuevo(){
System.out.println("Comenzando un HiloNuevo...");

}

public void run(){
System.out.println("Llamando al método run de HiloNuevo...");
for(int i=0;i<5;i++)
{
System.out.println(i);
}
System.out.println("Terminando el trabajo...");
}

}

Al ejecutar el código anterior nos da un resultado como el siguiente:

Dentro de main...
Comenzando un HiloNuevo...
Llamando al método run de HiloNuevo...
0
1
2
3
4
Terminando el trabajo...

Es importante tomar en cuenta que al llamar el método start(), se ejecuta el trabajo definido en el método run() en un nuevo e independiente proceso, de igual manera podemos llamar directamente al método run() y el mismo trabajo se ejecutará pero no comenzará un proceso independiente y no tendrá sentido que utilicemos los hilos.

Para saber qué hilo se encuentra en ejecución en un momento determinado, existe el método estático Thread.currentThread().getName() el cual te devuelve un valor de tipo cadena con el nombre del hilo en ejecución, si no has definido un nombre con el método setName(), de igual manera el proceso lo tendrá, algo muy parecido a Thread-0.


Ejecutando varios hilos al mismo tiempo::

Vamos a analizar un ejemplo de 3 hilos realizando el mismo trabajo, comenzaremos con una clase que implementa la interfaz Runnable, la cual es instanciada y enviada a 3 diferentes hilos, posteriormente le damos un nombre a cada uno de ellos e iniciamos su trabajo con el método start().

public class Hilos {
public static void main (String[] args){
HiloNuevo hn = new HiloNuevo();
Thread uno = new Thread(hn);
Thread dos = new Thread(hn);
Thread tres = new Thread(hn);
uno.setName("Luis");
dos.setName("Carlos");
tres.setName("María");
uno.start();
dos.start();
tres.start();
}
}

class HiloNuevo implements Runnable{
public void run(){
for(int i=0;i<3;i++)
{
System.out.println("Comenzado por " + Thread.currentThread().getName() + ", i = "+i);
}
}
}

Una vez que ejecutamos lo anterior nos dará un resultado parecido a lo siguiente:

Comenzado por Luis, i = 0
Comenzado por Luis, i = 1
Comenzado por Luis, i = 2
Comenzado por Carlos, i = 0
Comenzado por Carlos, i = 1
Comenzado por Carlos, i = 2
Comenzado por María, i = 0
Comenzado por María, i = 1
Comenzado por María, i = 2

...¿o no?, si lo volvemos a ejecutar (al menos en mi máquina) obtengo lo siguiente:

Comenzado por Luis, i = 0
Comenzado por Carlos, i = 0
Comenzado por Luis, i = 1
Comenzado por Carlos, i = 1
Comenzado por Luis, i = 2
Comenzado por María, i = 0
Comenzado por María, i = 1
Comenzado por María, i = 2
Comenzado por Carlos, i = 2

Vaya sorpresa, cada vez que se ejecuta obtengo un resultado diferente, por lo tanto podemos definir que el comportamiento de los hilos no es predecible, anteriormente he mencionado que "cuando se trata de hilos, muy pocas cosas está garantizadas", lo cual significa que los hilos no necesariamente se ejecutarán en el orden en que fueron iniciados o que una vez que el hilo se inició no parará hasta terminar su trabajo, lo cierto es que nada está garantizado más que lo siguiente:

"Cada hilo se iniciará y se ejecutará hasta que se complete"

No hay un orden ni nada que garantice el funcionamiento de varios hilos al mismo tiempo, sin embargo, cada hilo en particular trabaja con normalidad, si observamos solamente el comportamiento del hilo de nombre Carlos, vemos que i va de 0 a 2, al igual que Luis y María, pero cuando todos trabajan junto, nada asegura que se ejecutarán desde el inicio hasta el final sin interrupciones, así trabajan los hilos en Java.

Debes de saber de igual manera que una vez que se ha llamado al método start() de un hilo, no puedes volver a realizar otra llamada al mismo método, independientemente de si el hilo ha terminado de realizar lo que está definido dentro de su método run() o no, si vuelves a llamar al método start() en un hilo que ya lo llamó previamente, obtendrás una excepción java.lang.IllegalThreadStateException.

Hasta el momento hemos visto 3 tipos de estado de un hilo: nuevo (new),en ejecución (runnable) y muerto (dead). Existen algunos otros estados de un hilo que analizaremos más adelante.

Hasta aquí llega la segunda parte...

Más sobre programación en Java aquí.

Comentarios

  1. Este blog ha sido eliminado por un administrador de blog.

    ResponderBorrar
  2. Muy bueno.. Me has ayudado a aclarar el tema. Gracias.

    ResponderBorrar
  3. De verdad que me ayudo leer mucho sobre los Threads, era algo que no lo tenia muy claro, pero lo expresaste de una manera sencilla, facil de entender y muy completa.

    Muchas gracias!

    ResponderBorrar
  4. Hola, estuve pensando... deberias colocar un tema sobre semáforos en Java.. o si puedes colocar alguna información que lo explique de manera sencilla y con ejemplos para que uno pueda comenzar... gracias!

    ResponderBorrar
  5. En las proximas semanas estaré publicando sobre diversos temas en Java, la idea es cubrir por completo aquellos que se necesitan para pasar el examen de certificación SCJP, solo que he tenido una carga de trabajo un tanto intensa pero sigue visitando mi blog y pronto encontrarás muchos más temas sobre esto.

    ResponderBorrar
  6. Muy buena la entrada, estoy estudiando ingenieria en Sistemas y me ha ayudado muchisimo. Saludos

    ResponderBorrar
  7. Muy buen trabajo te felicito. Me esta ayudando mucho para mis tareas de Topicos selectos de programacion Grasias XD ^_^

    ResponderBorrar
  8. Muchas gracias por los ejemplos; acabe de realizarlos y funcionan; solo tengo una pregunta como puedo asociarlos con las pilas de procesos, simulando la comunicacion entre el procesador y la memoria??

    De antemano milgracias por los ejemplos expuestos, me aclaran dudas y me generan otras!!

    ResponderBorrar
  9. Excelente forma de explicar, muchisimas gracias por publicar tus conocimientos, lo que has aprendido y sobre todo tomarte el teimpo para explicarlo de una forma clara.

    ResponderBorrar
  10. Amigo me has salvado la vida tu tip entre la diferencia en invocar al hilo con el metodo run y el start es genial. Yo usaba el run() por eso no habia indepedencia entre mis dos hilos activos. Eres crack...

    ResponderBorrar
  11. Emmm..... Hola! Que tal?

    Respecto al orden, pues a mi me funciono, o por el contrario no le lo ha devuelto en desorden... Utilizando el metodo sleep(1000) (el 1000 porque fue lo que quise poner) pero obviamente este es con el try cash...

    Bueno en fin con este metodo utilizandolo en el constructor que implementa runnable o que extienda de thread como lo maneje, no me lo ha tirado en desorden!

    Saludes!

    ResponderBorrar

Publicar un comentario

Este es un espacio abierto, puedes escribir lo que gustes respetando los siguientes puntos:

1.- Lo que escribas esté relacionado con el post, si gustas contactarme puedes hacerlo aqui.

2.- Todo es cuestionable, aunque ten en cuenta que existen formas de hacerlo, evita las agresiones y revisa tu lenguaje antes de publicar un comentario.

3.- Siempre hay tres verdades: tu verdad, mi verdad y la verdad, por lo que opiniones diferentes no necesariamente son equivocadas.

4.- Los comentarios son una forma de discusión abierta, por lo que al publicar uno, implícitamente entras a una discusión, con todo lo que esto representa.

5. Me reservo el derecho de eliminar comentarios que no respeten las condiciones mencionadas anteriormente.

Toma en cuenta que puedes utilizar emoticones en tu comentario, para ver una lista de los disponibles da clic en este enlace.

Entradas más populares de este blog

3 sencillos pasos para tramitar la ayuda por desempleo de la AFORE

¿Tienes dinero ahorrado en tu AFORE y en este momento no estás trabajando o estás trabajando pero no tienes seguro social? Si respondiste sí a la pregunta anterior entonces hay una buena noticia para ti: puedes retirar una parte del dinero que tienes ahorrado. Y lo mejor, es muy sencillo. En este artículo te diré paso a paso qué hacer para obtener ese dinero, sin tecnicismos legales ni nada por el estilo, simple y sencillamente lo que necesitas saber. Paso Número 1: Obtener los últimos 2 estados de cuenta de tu Afore Esto en la mayoría de los casos es sumamente sencillo ya que dichos estados de cuenta llegan directamente al domicilio del ahorrador, si este es tu caso puedes saltar lo restante en este punto y continuar con el paso número 2, en caso contrario sigue leyendo… Si no tienes tus estados de cuenta debes ponerte en contacto con la empresa encargada de administrar tu ahorro para que te los proporcione, normalmente te van a pedir una identificación oficial, comprobante de

Conectar una base de datos en MySQL con NetBeans

NetBeans es una plataforma para el desarrollo de aplicaciones de escritorio usando Java y a un Entorno integrado de desarrollo (IDE) desarrollado usando la Plataforma NetBeans. Si eres un programador y desarrollas tus aplicaciones en Java seguramente necesitarás conectar una base de datos tipo MySQL a este entorno algún día, bueno, si lo necesitas ahora, he aquí una explicación paso a paso de cómo conectar ambas herramientas.

4 extraordinarias aplicaciones espía para Android

Le andas haciendo al James Bond y necesitas grabar video, voz o tomar fotos desde tu dispositivo Android sin ser notado? Aquí 4 excelentes aplicaciones que facilitarán tus hazañas de 007 en menos de lo que canta un gallo.

c606 c6nf5g4r6 e3 tec3ad6 [Como configurar el teclado]

¿Problemas al escribir con el teclado? ¿Tratas de escribir la letra ‘o’ y sale el número ‘6’ o algo por el estilo? La solución puede ser más simple de lo que parece. La solución a tu problema tras el salto...

Conexión, consulta y ejecución de sentencias en MySQL con Java

Anteriormente escribí este mismo artículo pero para bases de datos en Oracle . En este artículo prácticamente me copio y pego para explicar paso a paso cómo realizar la conexión a MySQL en Java, así como la forma de realizar consultas a los registros existentes y ejecutar sentencias de inserción, borrado y actualización de datos. Al final del artículo tendremos una clase que encapsulará todos los procedimientos necesarios para trabajar con la base de datos.