viernes, 19 de octubre de 2012

Ejemplo de señalización ( wait() y notify() )

En este ejemplo vamos a tener 3 clases: una clase Main, una clase Saludo y una clase Personal (Hilo).

Clase Main:

public class Main {
   
    public static void main(String[] args) {
       
        // Objeto en comun, se encarga del wait y notify
        Saludo s = new Saludo();
       
        /*Instancio los hilos y le paso como parametros:
         *
         * El Nombre del Hilo(en este caso es el nombre del personal)
         * ----El objeto en comun (Saludo)----
         * Un booleano para verificar si es jefe o empleados
         *
        */       
        Personal Empleado1 = new Personal("Pepe", s, false);
        Personal Empleado2 = new Personal("José", s, false);
        Personal Empleado3 = new Personal("Pedro", s, false);
        Personal Jefe1 = new Personal("JEFE", s, true);
       
             //Lanzo los hilos       
            Empleado1.start();           
            Empleado2.start();           
            Empleado3.start();           
            Jefe1.start();

    }
}

Clase Personal:

import java.util.logging.Level;
import java.util.logging.Logger;

public class Personal extends Thread{
    String nombre;
    Saludo saludo;
    boolean esJefe;
   
    public Personal(String nombre, Saludo salu, boolean esJefe){
        this.nombre = nombre;
        this.saludo = salu;
        this.esJefe = esJefe;
    }
   
    public void run(){
        System.out.println(nombre + " llegó.");
        try {
            Thread.sleep(1000);
            //Verifico si es personal que esta es jefe o no
            if(esJefe){
                saludo.saludoJefe(nombre);
            }else{
                saludo.saludoEmpleado(nombre);
            }
           
        } catch (InterruptedException ex) {
            Logger.getLogger(Personal.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Clase Saludo:

import java.util.logging.Level;
import java.util.logging.Logger;

public class Saludo {
   
    public Saludo(){       
    }
   
    /* Si no es jefe, el empleado va a quedar esperando a que llegue el jefe
    Se hace wait de el hilo que esta corriendo y se bloquea, hasta que
    se le avise que ya puede saludar*/
    public synchronized void saludoEmpleado(String nombre){
        try {
            wait();
            System.out.println("\n"+nombre.toUpperCase() + "-: Buenos días jefe.");
        } catch (InterruptedException ex) {
            Logger.getLogger(Saludo.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
   
    //Si es jefe, saluda y luego avisa a los empleados para que saluden
    // El notifyAll despierta a todos los hilos que esten bloqueados
    public synchronized void saludoJefe(String nombre){
        System.out.println("\n****** "+nombre + "-: Buenos días empleados. ******");
        notifyAll();
    }    
}

Salida del programa por consola:

Pepe llegó.
José llegó.
Pedro llegó.
JEFE llegó.

****** JEFE-: Buenos días empleados. ******

PEPE-: Buenos días jefe.

JOSÉ-: Buenos días jefe.

PEDRO-: Buenos días jefe.

6 comentarios:

  1. Felicidades me han servido mucho tus ejemplos.

    ResponderEliminar
  2. Muchas gracias ^^ me fue de gran utilidad :3

    ResponderEliminar
  3. Hola,
    existe un pequeño problema en el código: si el jefe llega antes que un empleado éste no despertará de su wait, ya que el notifyAll() ya ha sido llamado por el jefe.
    La solución es utilizar un booleano que nos indique si el jefe ya ha llegado o no. Y en función de él saludar al jefe o disculpar el retraso.

    ResponderEliminar
    Respuestas
    1. Muy cierto. Yo tambien me habia dado cuenta de ese detalle.

      Eliminar
  4. hola muy buen ejemplo queria saber si tienes otro ejemplo similar donde ocupas tiempo ya que me encuentro con un dilema de un programa de una carrera pero ocupo tiempo

    ResponderEliminar