Sei sulla pagina 1di 1

Inicio Lee el blog desde Android Proyectos libres Sobre mi Tutoriales

PROGRAMAR ES SENCILLO permanece al día vía rss

¡Porque programar no es complicado!

[Java] Monitores, ejemplo 1

GRAVATAR
Productor Consumidor
Publicado: 25 noviembre, 2014 en Java
Etiquetas:concurrencia, concurrency, Fumadores, Java, monitores, notifiAll, notify, Productor
consumidor, synchronized, wait

La concurrencia es algo que suele costar ver pero que en realidad no es tan complicada, en Java podemos utilizar los
monitores y las hebras para realizar tareas concurrentes.

¿Qué es un monitor?
LOGOTIPO DEL BLOG

Los monitores son objetos destinados a ser usados sin peligro por más de un hilo de ejecución. Mas información.

¿Qué métodos nos proveen los monitores para la implementación de tareas concurrentes?

synchronized

Al poner la palabra reservada synchronized en un método en Java estamos indicando que en ese método tenemos
una sección crítica del código y por lo tanto las hebras que accedan a dicho método deberán hacerlo de forma
síncrona.

wait()

Con wait bloqueamos una hebra.


Logotipo del blog por Arturo Reina

notify()

LICENCIA Con notify desbloqueamos una de las hebras que han sido bloqueadas al intentar acceder a un método sincronizado.
Después de esta llamada la hebra desbloqueada podrá tener acceso sin peligro a la zona crítica del método
sincronizado.
Esta obra está bajo una Licencia Creative
Commons Atribución 4.0 Internacional.
notifyAll()

BUSCAR EN EL BLOG
La diferencia entre notify y notifyAll es que con este último desbloqueamos todas las hebras que fueron bloqueadas
en un método síncrono y estas competirán por acceder a la zona crítica. Las hebras que no consigan acceder volverán
a ser bloqueadas.
Buscar en este sitio

Sabiendo todo esto podemos crear aplicaciones concurrentes mediante el uso de monitores, vamos a poner el
Seguir Programar es sencillo 5 ejemplo del productor consumidor de buffer limitado.

Tenemos un productor que va produciendo números de uno en uno y una serie de consumidores que irán
DAME UN ME GUSTA
consumiendo dichos números. El productor no podrá producir mas de un número y los consumidores no podrán
consumir nada si no se ha producido antes.

Primeramente nos crearemos la clase Contenedor, que será donde el productor producirá los números y de donde los
consumidores los consumirán:

1 public class Contenedor


2 {
3 private int contenido;
4 private boolean contenedorlleno = Boolean.FALSE;
5
6 /**
7 * Obtiene de forma concurrente o síncrona el elemento que hay en el contenedor
8 * @return Contenido el contenedor
9 */
10 public synchronized int get()
11 {
12 while (!contenedorlleno)
META 13 {
14 try
Registrarse 15 {
16 wait();
Acceder 17 }
RSS de las entradas 18 catch (InterruptedException e)
19 {
RSS de los comentarios 20 System.err.println("Contenedor: Error en get ‐> " + e.getMessage());
21 }
WordPress.com 22 }
23 contenedorlleno = Boolean.FALSE;
24 notify();
CATEGORÍAS 25 return contenido;
26 }
27
Android Bash C++ Fortran GitHub 28
29
/**
* Introduce de forma concurrente o síncrona un elemento en el contenedor
Java Linux MySQL OpenGL Perl PHP PLSQL 30 * @param value Elemento a introducir en el contenedor
31 */
Sin categoría Tutoriales Ubuntu Windows 32 public synchronized void put(int value)
XML 33 {
34 while (contenedorlleno)
35 {
36 try
37 {
38 wait();
39 }
40 catch (InterruptedException e)
41 {
42 System.err.println("Contenedor: Error en put ‐> " + e.getMessage());
43 }
44 }
45 contenido = value;
46 contenedorlleno = Boolean.TRUE;
47 notify();
48 }
49 }

Nos creamos la clase Productor:

1 public class Productor implements Runnable


2 {
3 private final Random aleatorio;
4 private final Contenedor contenedor;
5 private final int idproductor;
6 private final int TIEMPOESPERA = 1500;
7
8 /**
SÍGUEME EN TWITTER 9 * Constructor de la clase
10 * @param contenedor Contenedor común a los consumidores y el productor
11 * @param idproductor Identificador del productor
12 */
13 public Productor(Contenedor contenedor, int idproductor)
14 {
15 this.contenedor = contenedor;
16 this.idproductor = idproductor;
17 aleatorio = new Random();
18 }
19
20 @Override
21 /**
22 * Implementación de la hebra
23 */
24 public void run()
25 {
26 while(Boolean.TRUE)
27 {
28 int poner = aleatorio.nextInt(300);
29 contenedor.put(poner);
30 System.out.println("El productor " + idproductor + " pone: " + poner);
31 try
32 {
33 Thread.sleep(TIEMPOESPERA);
34 }
35 catch (InterruptedException e)
36 {
37 System.err.println("Productor " + idproductor + ": Error en run ‐> " + e.getMessage());
38 }
39 }
40 }
41 }

Nos creamos la clase Consumidor:

SIGUE EL BLOG POR EMAIL 1 public class Consumidor implements Runnable


2 {
Introduce tu dirección de correo electrónico para seguir 3 private final Contenedor contenedor;
este Blog y recibir las notificaciones de las nuevas 4 private final int idconsumidor;
publicaciones en tu buzón de correo electrónico. 5
6 /**
Únete a otros 11 seguidores 7 * Constructor de la clase
8 * @param contenedor Contenedor común a los consumidores y el productor
Introduce tu dirección de correo electrónico
9 * @param idconsumidor Identificador del consumidor
10 */
Seguir 11 public Consumidor(Contenedor contenedor, int idconsumidor)
12 {
13 this.contenedor = contenedor;
14 this.idconsumidor = idconsumidor;
15 }
16
17 @Override
18 /**
19 * Implementación de la hebra
20 */
21 public void run()
22 {
23 while(Boolean.TRUE)
24 {
25 System.out.println("El consumidor " + idconsumidor + " consume: " + contenedor.get());
26 }
27 }
28 }

Y por último el código principal, clase llamada ProductorConsumidor por ejemplo, quedaría de la siguiente forma:

1 public class ProductorConsumidor


2 {
3 private static Contenedor contenedor;
4 private static Thread productor;
5 private static Thread [] consumidores;
6 private static final int CANTIDADCONSUMIDORES = 5;
7
8 /**
9 * @param args the command line arguments
10 */
11 public static void main(String[] args)
12 {
13 contenedor = new Contenedor();
14 productor = new Thread(new Productor(contenedor, 1));
15 consumidores = new Thread[CANTIDADCONSUMIDORES];
16
17 for(int i = 0; i < CANTIDADCONSUMIDORES; i++)
18 {
19 consumidores[i] = new Thread(new Consumidor(contenedor, i));
20 consumidores[i].start();
21 }
22
23 productor.start();
24 }
25 }

Os dejo el código del productor consumidor en Java: [Java]_Productor_Consumidor

También os dejo el código del problema de los fumadores en Java realizado con
monitores: [Java]_Problema_Fumadores

Tu voto:

Rate This

Comparte esto:

Twittear 1 Share submit  Imprimir


1  Correo electrónico

Relacionado

[Android] Hebras - Ejemplo: [Java] Tratamiento de ficheros [Android] Agregando emojis en


Cronómetro XML Android Studio

comentarios
Rodrigo dice:
12 abril, 2016 a las 3:59 pm

Muy bueno el ejemplo muchas gracias, practicando cosas hice algún cambio interesante.
En el productor hice la impresión antes del put, porque a veces salía antes la impresión del consumidor, tambien intenté
que el productor no tuviera sleep, esto a la larga me dejaba a los consumidores y al productor en sleep, lo corregí
cambiando el notify del get por notifyALL().


0 1 Rate This
Responder

Deja un comentario
Introduce aquí tu comentario...

[Android] Tablas dinámicas en Android [Android] NavigationDrawer

Blog de WordPress.com.

Potrebbero piacerti anche