Java wait notify y threads

Todos conocemos la clase Object y los métodos principales que posee como equals y hashcode. Sin embargo a mucha gente le cuesta entender para que sirven java wait notify,dos métodos que pertenecen a la clase Object y estan relacionados con programación concurrente, vamos a abordarlo. Para ello vamos a crearnos dos clases sencillas (Bolsa y Producto) donde una Bolsa contiene varios Productos.

001

Vamos a ver su código:


package com.arquitecturajava;

import java.util.ArrayList;

public class Bolsa {

private ArrayList<Producto> listaProductos = new ArrayList<Producto>();

public void addProducto(Producto producto) {

if (!estaLlena())
 listaProductos.add(producto);
 }

public ArrayList<Producto> getListaProductos() {
 return listaProductos;

}

public int getSize() {
 return listaProductos.size();
 }
 public boolean estaLlena() {

return listaProductos.size() >= 5;
 }
}

package com.arquitecturajava;

public class Producto {

 private String nombre;

 public String getNombre() {
 return nombre;
 }

 public void setNombre(String nombre) {
 this.nombre = nombre;
 }
}

Lo único que tiene de peculiar la bolsa que hemos creado es que no permite que se le añadan más de 5 elementos. Ahora vamos a construir dos Threads un primer Thread que va poco a poco llenando la bolsa (thread main)  y otro Thread que cuando la bolsa este llena la envía. Vamos a ver el Thread que envía la bolsa:


package com.arquitecturajava;

public class HiloEnvio extends Thread {

private Bolsa bolsa;

public HiloEnvio(Bolsa bolsa) {
 super();
 this.bolsa = bolsa;
 }

@Override
 public void run() {

if (bolsa.estaLlena() != true) {

try {
 synchronized (bolsa) {
 bolsa.wait();
 }

 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }

 System.out.println("Enviando la bolsa con "+ bolsa.getSize()+"elementos");
 }

}

public Bolsa getBolsa() {
 return bolsa;
 }

public void setBolsa(Bolsa bolsa) {
 this.bolsa = bolsa;
 }

}

Este Hilo se encarga de sacarnos por pantalla el mensaje de “Enviando la bolsa con 5 elementos” . Para ello recibe la Bolsa como parámetro y chequea que esta llena. Usa un bloque de código sincronizado (syncronized)  . Este bloque de código coordina el trabajo entre nuestros dos Threads y permite que un Thread llene la Bolsa y cuando este llena el otro Thread la envíe.

002

Lamentablemente ambos Threads deben de estar sincronizados ya que hasta que la bolsa no este llena no la podemos enviar. Para sincronizar el trabajo de los Threads usamos la pareja wait notify. De tal forma que nuestro primer HiloEnvio se pondrá a esperar(wait) hasta que la Bolsa este llena antes de enviarla. Para rellenar la bolsa usamos el Thread del programa principal que cada segundo añadirá un nuevo elemento a la lista.


package com.arquitecturajava;

public class Principal {

 public static void main(String[] args) {

 Bolsa bolsa= new Bolsa();
 HiloEnvio hilo= new HiloEnvio(bolsa);
 hilo.start();

 for(int i=0;i<=10;i++) {

 Producto p= new Producto();
 try {

 synchronized (bolsa) {

 Thread.sleep(1000);
 if (bolsa.estaLlena()) {
 bolsa.notify();
 }
 }

 } catch (InterruptedException e) {
 e.printStackTrace();
 }

 bolsa.addProducto(p);
 System.out.println(bolsa.getSize());

 }

 }

}

Como vemos el método main va añadiendo productos a la Bolsa y cuando esta llena notifica (notify) al otro Thread de que ya  puede procesarlo saliendo del estado wait en el que se encuentra.

003

 

El uso de wait() y notify() es muy habitual en programación concurrente y son parte de la clase Object ya que lo que bloqueamos y sincronizamos es el acceso a cada uno de los objetos. Si ejecutamos el programa nos saldrá por consola el siguiente resultado:

005

En cuanto tenemos 5 elementos y la bolsa llena el Thread principal no puede añadir más pero ha notificado al otro Thread que en cuando pueda realice su trabajo que es enviar la bolsa.

It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

About Cecilio Álvarez Caules

Cecilio Álvarez Caules Sun Certified Enterprise Architech (J2EE/JEE).

13 Responses to Java wait notify y threads

  1. sebastian 19 Abril, 2015 at 18:57 #

    cecilio buen dia… la consulta es sobre su libro arquitectura java solida.. estoy sigiuiendolo y me quede en una parte… llegado un momento en la JSP mostrar libro…. se le agrega un filtro para mostrar solo las categoras que el usuario quiera… mi pregunta es cuando se pulsa ese boton, se envia el parametro categoria del combo (select)… pero quien recibe esos datos… tengo que crear otra JSP… o es la misma JSP mostrarlibros la que se encarga de gestionar esos datos?……. gracias

  2. diego 6 Marzo, 2015 at 20:34 #

    como realizar un threads que verifique mi base de datos si algún producto se esta agotando y que me envié una notificación en java no se por donde empezar xD

    • Cecilio Álvarez Caules 6 Marzo, 2015 at 23:11 #

      Podrías usar un servicio de timer de EJB que cada x tiempo te consulte .. por ejemplo

  3. sebastian 4 Febrero, 2015 at 16:16 #

    Hola nuevamente Cecilio…. estoy siguiendo tu libro y me surgio otra doda…. esta ves no tiene que ver con los hilos de ejecucion pero no sabia donde hacer la consulta asi que postie aca….. yo venia siguiendo los ejemplos y me detuve en la parte en la cual… haciendo uso del principio dry creas una clase java que se encarga de gestionar las consultas sql de accion y seleccion para simplificar los codigos de las paginas JSP…… el problema es que yo creo un proyecto java, un paquete y la clase respectiva todo esto dentro de la aplicacion web…. pero cuando quiero instanciar un objeto de la clase java desde la jsp y correr la aplicacion en el servidor no me funciona me muestra esta excepcion…..

    org.apache.jasper.JasperException: No se puede compilar la clase para JSP:
    Ha tenido lugar un error en la línea: [16] en el fichero java generado: [C:\Users\admiral\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\Aplicacion01HTML\org\apache\jsp\mostrarLibro_jsp.java]
    Only a type can be imported. arquitecturajava.DataBaseHelper resolves to a package

    tendria que colocar el proyecto dentro de una ubicacion especial? si podrias ayudarme te lo agradeceria porque me quede alli y no puedo proseguir con el curso…. gracias.

  4. sebastian 31 Diciembre, 2014 at 6:52 #

    Hola Cecilio, estaba aprendidendo java…y tenia algunas dudas con los subprocesos. vi tu explicacion y me aclaro un poco mis dudas pero igual me quedaron algunas. en el ejemplo que nos distes. en esta parte en particular

    public void run() {

    if (bolsa.estaLlena() != true) {

    try {
    synchronized (bolsa) {
    bolsa.wait();
    }

    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    cuando llamamos a Start() y comienza la ejecucion del hiilo…… luego … si la bolsa aun no esta llena suspendemos el subproceso… llamando al metodo wait de la clase Thread… mi duda es… quien es el que puede invocar al metodo wait….? puede hacerlo cualquier objeto?…. siempre que se realize una llamada a este metodo sea en el hilo principal o en otro creado por mi…. el hilo se suspendera?…. y para reactivar el hilo suspendido… es nesecario realizar una llamada a notify en el mismo objeto que libero el monitor?….
    gracias por publicar … descargue el libro de arquitectura solida.. pero aun no he comenzado con el… estoy despejando algunas dudas que tengo primero… no quiero avanzar sin entender lo basico… saludos.

    • Cecilio Álvarez Caules 1 Enero, 2015 at 12:47 #

      Cualquier objeto puede llamar al método wait() y suspenderá la ejecución el hilo actual que pasará a un estado de waiting. Una vez hecho esto solo se despertará tras un notify .

      • silencioso 2 Enero, 2015 at 22:13 #

        hay que tener en cuenta que wait y notify solo tienen efecto en un contexto sincronizado, tal como nos lo muestra él en su ejemplo

      • sebastian 5 Enero, 2015 at 10:35 #

        gracias Cecilio por tomarte el tiempo de responder.

        • Cecilio Álvarez Caules 6 Enero, 2015 at 12:16 #

          de nada 🙂

  5. Javero 17 Diciembre, 2014 at 11:41 #

    Hola, Cecilio.

    En primer lugar agradecerte el esfuerzo por mantener una “web” como esta. Es realmente muy útil.

    Solo decirte, de manera constructiva y para darle más categoría si cabe a la página, que no tuviera tantas faltas gramaticales y ortográficas.

    Saludos,
    Javero

    • Cecilio Álvarez Caules 17 Diciembre, 2014 at 11:45 #

      Me apunto las ideas gracias por los comentarios 🙂

Trackbacks/Pingbacks

  1. Java Callable Interface y su uso - Arquitectura Java - 8 Diciembre, 2016

    […] artículos relacionados : Java Executor Service y Threading ,Java wait notify y threads , JavaScript Promise y la programación […]

  2. Java Garbage Collector - Arquitectura Java - 18 Agosto, 2015

    […] Otros artículos relacionados : Java Collection Performance  , Java  Fluid Interface , Java Threads […]

Deja un comentario