Ir al contenido principal

Hilos en Java(Threads) parte 5

Lo último que necesitamos saber con los hilos es el cómo interactúan entre ellos, cómo es que se comunican cuando tienen o liberan el seguro de un objeto en particular. La clase Object cuenta con 3 métodos que ayudan a los hilos a comunicarse entre ellos, los métodos son: wait(), notify() y notifyAll(). Algo importante a tomar en cuenta con los hilos es:

wait(), notify() y notifyAll() deben ser llamados desde dentro de un contexto sincronizado. Un hilo no puede invocar wait() o notify() en un objeto a menos de que posea el seguro de dicho objeto.
Más info tras el salto...




De la misma manera en que todo objeto posee un seguro, cada objeto puede tener una lista de hilos que están esperando una notificación del objeto. Un hilo se posiciona en esta lista de espera por medio de una llamada al método wait() del objeto al que está esperando. Desde ese momento, el hilo no ejecuta ninguna instrucción hasta que el método notify() es llamado por el objeto. Si existen varios hilos en la cola de espera del objeto, solo uno podrá ser escogido (sin un orden garantizado) por el programador de hilos para acceder a dicho objeto y obtener su seguro. Un ejemplo en código sería el siguiente:

public class ThreadA {

public ThreadA() {
}

public static void main(String[] args)
{
ThreadB b = new ThreadB();
b.start();

synchronized(b){
try {
System.out.println("Esperando a que B se complete...");
b.wait();
} catch (InterruptedException ex) { }

System.out.println("Total:" +b.total);
}
}
}

class ThreadB extends Thread{
long total;

public void run(){
synchronized(this)
{
for(long i=0; i<1000000000;i++)
total+=i;
notify();
}

}
}

Si lo ejecutamos obtenemos algo así...

Esperando a que B se complete...
Total:499999999500000000

En caso de que omitiéramos la llamada a wait(), el resultado sería el siguiente:

Total:0

Un punto a tomar en cuenta es que para poder llamar al método wait(), se tuvo que sincronizar el bloque de código y obtener el seguro de b, de lo contrario se obtiene una excepción de tipo java.lang.IllegalMonitorStateException.

Como se ha mencionado anteriormente, un solo objeto puede tener una lista de espera de varios hilos, en dichos casos es recomendable utilizar notifyAll() en vez de notify(), ya que notifyAll() notificará que está a punto de liberar el seguro del objeto a todos los hilos de la lista de espera.

Repasando, los métodos definidos por la clase Object son wait(), notify() y notifyAll(). Los métodos definidos por la clase Thread son start(), yield(), sleep() y join(), sleep() y yield() son estáticos mientras que start() y join() no lo son. El método definido en la interfaz Runnable es run().

Hemos terminado con los Hilos en Java. Si tienes alguna duda deja tu comentario.

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

Comentarios

  1. muy bueno, un abrazo desde Argentina!

    ResponderEliminar
  2. esta muy bien el programa pero le sugieron que suban mas para analixarlo gracias.

    ResponderEliminar
  3. oye muchas gracias por este aporte el ejemplo es muy claro, pero creo que lo podrias ampliar un poco mas gracias

    ResponderEliminar
  4. Me vino muy bien todo esto. Un saludo desde España

    ResponderEliminar
  5. Muy útil. Me los he ventilado en media hora haciendo pruebas de por medio. Voy a hacer como neo y decir "Ya se hilos" aunque se pasa de pretencioso por mi parte :D

    ResponderEliminar
  6. Gracias! desde México.

    asi es como se deben de explicar las cosas, sencillas y con codigo funcional, para que uno pueda hacer sus pruebas, gracias!

    ResponderEliminar
  7. Disculpa y para pasarle parametros a un hilo ?

    se usaria la misma logica en la que acceden a una variable (como en el ejemplo del banco) y sincronizarlos o darles tiempos en los que van a estar accediendo a las variables ?

    o existe algun otro modo para pasarle directamente un parametro como lo haces con el setName() e irle seteando nombres o como ?

    ResponderEliminar
  8. Simplemente Excelente!!! Thank so much....

    ResponderEliminar
  9. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  10. He programado a mi forma el ejemplo de la cuenta bancaria y varios hilos con el nombre de la persona que va a retirar dinero. Todos podían sacar gracias a synchornized, pero el orden de ejecución era aleatorio. Entonces le introduje el uso de wait y response, a saber: Los hilos llevan asociado un mismo objeto, implementación de Runnable, que es con el que sincronizo dentro del método run. Ahora mismo, dentro de mi main, el código viene a ser algo así:


    Hilo cuenta = new Hilo(); // hilo implementa a la interfaz runnable

    Thread juanito = new Thread(cuenta, "Juanito");
    Thread pepito = new Thread(cuenta, "Pepito");
    Thread lourdes = new Thread(cuenta, "Lourdes");
    Thread jesus = new Thread(cuenta, "Jesús");
    Thread edelmiro = new Thread(cuenta, "Edelmiro");


    juanito.start();


    synchronized(cuenta) {
    try
    cuenta.wait();
    }
    catch (InterruptedException e) { }
    pepito.start();
    }


    synchronized(cuenta) {
    try
    {
    cuenta.wait();
    }
    catch (InterruptedException e) { }
    lourdes.start();
    }


    synchronized(cuenta) {
    try {
    cuenta.wait();
    }
    catch (InterruptedException e) { }

    jesus.start();
    }

    synchronized(cuenta) {
    try {
    cuenta.wait();
    }
    catch (InterruptedException e) { }

    edelmiro.start();
    }

    Esto me da como resultado que tengo controlado el orden de ejecución de dichos hilos, que aunque no es muy práctico programarlo por hilos, me valeparala comprensión de los conceptos. Pero así no fue como empecé a trabajar. En un principio, esperé a los propios hilos en lugar del objeto cuenta:

    synchronized(juanito) {
    try {
    juanito.wait();
    }
    catch (InterruptedException e) { }
    pepito.start();
    }


    synchronized(pepito) {
    try
    {
    pepito.wait();
    }
    catch (InterruptedException e) { }
    lourdes.start();
    }

    Es decir, Pepito espera a Juanito, Lourdes espera a Pepito, y así sucesivamente. Me pareció intuitivo, pero me resulta curioso que funcione cuando no existe una correspondencia entre el hilo y el objeto del que obtengo el seguro, que siempre es el mismo. Y más curioso aún, que no necesite hacer un Notify en este caso, funciona igual sin él. Imagino que al enviar la orden wait a un hilo, cuando dicho hilo muere, la espera se ha terminado. Aclárame esto, por favor. Y enhorabuena por el monográfico.

    ResponderEliminar
  11. Estupendo aporte, pero... sería posible que postearas una sexta parte ? algo como un ejercicio práctico que abarcara todo lo de hilos y los conceptos vistos en los 5 post anteriores, de verdad muchas gracias por tus aportes, personas como tú hacen grande la Internet :D

    ResponderEliminar
  12. Hector Salamanca Suarez15 de noviembre de 2012, 05:01

    Hola amigo, estupendos tutoriales de hilos, ¿sería posible que hicieras un ejemplo en donde trabajaras con un hilo padre e hilos hijo? no sé muy bien como hacerlo, espero tu respuesta, muy bueno tu blog!

    ResponderEliminar
  13. Jaja, estoy en las mismas, necesito ayuda con algún ejemplo sobre el manejo de un hilo padre y sus hilos hijos, deberías hacer una continuación de este post, a propósito, gracias por tus aportes.

    ResponderEliminar
  14. gracias gracias gracias mil GRACIAS!, Genial mi compa, aprendi hilos sin tantos compliques, realmente me han servido mucho tus tutoriales, he leido los comentarios de arriba y creo que también necesito aclaraciones acerca de cómo carajos manejar los hilos hijos respecto a su hilo padre.

    ResponderEliminar
  15. Buenos tutoriales, pero podrías subir algo relacionado con el multithreading ? (creo que se llama así) igual he aprendido mucho y me he sacado muchas dudas de encima con tus posts, gracias hermano!

    ResponderEliminar
  16. Hola Monillo007, en verdad tus tutoriales son como caídos del cielo <3 aunque tengo dudas acerca de cómo agrupar y trabajar los hilos, deberías hacer un 6to tutorial, te estaría muy agradecida ;) gracias por todo

    ResponderEliminar
  17. Hola Monillo, estoy feliz con tus tutoriales, increibles! me ha despejado muchas dudas sobre hilos, ¿será que puedes hacer uno que hable directamente sobre un hilo padre y varios de sus hilos hijos? ya varios visitantes han pedido lo mismo, voy a estar pendiente de tu blog, gracias por todo :3

    ResponderEliminar
  18. Excelente tutorial :y: Muchas Gracias!

    ResponderEliminar
  19. Genial amigo, me ha ayudado mucho. Saludos desde Venezuela.

    ResponderEliminar

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 domici…

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.

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.

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...