Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Introducción
La programación concurrente se da cuando múltiples actividades cooperan dentro de
una misma aplicación. Para que dicha cooperación sea posible, esas actividades
tendrán que comunicarse y sincronizarse. Por tanto, habrá que diseñar algunos
mecanismos que resuelvan tales necesidades de comunicación y sincronización, como
es el caso de los monitores.
1. Monitores
Un monitor es una estructura de datos que ofrece un conjunto de operaciones
públicas. […] Garantiza que sus operaciones se ejecutarán en exclusión mutua.
[…] Además, ofrece otra construcción interna: las condiciones. Cada condición
permite suspender hilos dentro del monitor liberando el acceso a este
(sincronización condicional). (Muñoz Escoí et al., 2012, p. 46)
Es importante aclarar que:
Resulta conveniente integrar la gestión de la sincronización en un lenguaje de
programación orientado a objetos. El run-time [tiempo de ejecución] del lenguaje
permitirá utilizar los mecanismos de sincronización necesarios para garantizar
exclusión mutua en el acceso a objetos compartidos y el soporte necesario para la
sincronización condicional, requiriendo un esfuerzo mínimo por parte del
programador. (Muñoz Escoí et al., 2012, pp. 48-49)
Entonces, podemos decir que “un monitor, en un lenguaje orientado a objetos, es una
clase que permite definir objetos que se compartirán de manera segura entre múltiples
hilos” (Muñoz Escoí et al., 2012, p. 49).
Ahora bien, ¿cómo podríamos aplicar nuestro caso de ejemplo de manera concreta?
Recordando que tenemos que implementar el problema denominado
productor/consumidor con buffer limitado, en el que el productor (turnero) irá generando
números de uno en uno y los consumidores (ventanillas) podrán acceder a esos
números. El productor no podrá producir más de un número y los consumidores no
podrán consumir nada, si no se ha producido antes.
/**
* Introduce de forma concurrente o síncrona un elemento en el buffer
* @param value Elemento a introducir en el contenedor
*/
public synchronized void put(int value)
{
while (bufferlleno)
{
try
{
wait();
}
catch (InterruptedException e)
{
System.err.println("Buffer: Error en put -> " + e.getMessage());
}
}
contenido = value;
bufferlleno = Boolean.TRUE;
notify();
}
}
/**
* Constructor de la clase
* @param contenedor Buffer común a los consumidores y el productor
* @param idproductor Identificador del productor
*/
public Productor(Buffer contenedor, int idproductor)
{
this.contenedor = contenedor;
this.idproductor = idproductor;
aleatorio = new Random();
}
@Override
/**
* Implementación del hilo
*/
public void run()
{
while(Boolean.TRUE)
{
int poner = aleatorio.nextInt(41);//tenemos 41 números por atender.
contenedor.put(poner);
System.out.println("El productor " + idproductor + " genera el número: " +
poner);
try
{
Thread.sleep(TIEMPOESPERA);
}
catch (InterruptedException e)
{
System.err.println("Productor " + idproductor + ": Error en run -> " +
e.getMessage());
}
}
}
}
/**
* Constructor de la clase
* @param contenedor Contenedor común a los consumidores y el productor
* @param idconsumidor Identificador del consumidor
*/
public Consumidor(Buffer contenedor, int idconsumidor)
{
this.contenedor = contenedor;
this.idconsumidor = idconsumidor;
}
@Override
/**
* Implementación del hilo
*/
public void run()
{
while(Boolean.TRUE)
{
System.out.println("La ventanilla " + idconsumidor + " llama al número: " +
contenedor.get());
}
}
}
productor.start();
}
Variantes de monitor
“Todo monitor debe mantener suspendido temporalmente (hasta que el otro se suspenda
o abandone el monitor) uno de los dos hilos involucrados en los efectos del método
notify(): el invocador (o notificador) o bien el que debía ser reactivado” (Muñoz Escoí et
al., 2012, p. 58). Es por esto que existen variantes que dan solución a esta situación,
cuyas características se describen en la tabla 1.
Las variantes de Brinch Hansen y Hoare priorizan al hilo que debía ser reactivado,
mientras que la variante de Lampson y Redell (que es la utilizada en los POSIX
threads y en Java) da mayor prioridad al hilo notificador.
[…]
Referencias
Goetz B., Peierls, T., Bloch, J., Bowbeer, J., Holmes, D. y Lea, D. (2006). Java
Concurrency in Practice. Estados Unidos: Addison-Wesley Professional
Muñoz Escoí, F. D., Argente Villaplana, E., Espinosa Minguet, A., Galdámez Saiz, P.,
García-Fornes, A., De Juan Marín, R. y Sendra Roig, J. (2012). Concurrencia y
sistemas distribuidos. Valencia, España: Universitat Politècnica