PracticaPC 01
Pág: 1/15
Práctica 1. Monitores en Java.
Programación Concurrente. 3º I.S.
Dpto. Lenguajes y Sistemas Informáticos
Escuela Técnica Superior de Ingeniería Informática y Telecomunicación
Universidad de Granada
Curso 2008/09
1 Código y métodos sincronizados.
Cada objeto tiene un cerrojo interno asociado. El cerrojo de un objeto solamente puede seradquirido por una sola hebra en cada momento. El cualificador synchronized sirve para hacer que
un bloque de código o un método sea protegido por el cerrojo del objeto. Para ejecutar un bloque o
un método sincronizado, las hebras deben adquirir el cerrojo del objeto, debiendo esperar si el
cerrojo ha sido ya adquirido por otra hebra.
Si obj es una referencia a un objeto, la siguiente construcciónhace que las hebras tengan
que adquirir el cerrojo del objeto para ejecutar el bloque de código sincronizado.
synchronized (obj) {
// bloque de codigo sincronizado
}
Si todas las secciones críticas están en el código de un único objeto, podremos utilizar this
para referenciar al objeto cuyo cerrojo vamos a utilizar:
synchronized (this) {
//bloque de codigo sincronizado
}
Podemos hacer que el cuerpoentero de un método sea código sincronizado:
tipo metodo ( ... ) {
synchronized (this) {
//codigo del metodo sincronizado
}
}
La siguiente construcción es equivalente a la anterior:
synchronized tipo metodo ( ... ) {
//codigo del metodo sincronizado
Práctica 1 - Programación Concurrente 3º I.S.
Pág: 2/15
}
Para construir un monitor en Java, creamos una clase con sus métodos sincronizados.De
esta forma solamente una hebra podrá ejecutar en cada momento el método del objeto.
El siguiente ejemplo muestra un monitor que implementa un contador:
class Contador { // monitor contador
private int actual;
public Contador(int inicial) {
actual = inicial;
}
public synchronized void inc() {
actual++;
}
public synchronized void dec() {
actual--;
}
public synchronized int valor() {
returnactual;
}
}
class Usuario extends Thread { // clase hebra usuaria
private Contador cnt;
public Usuario(String nombre, Contador cnt) {
super(nombre);
this.cnt = cnt;
}
public void run() {
for (int i = 0; i < 1000; i++) {
cnt.inc();
System.out.println("Hola, soy " + this.getName()
+ ", mi contador vale " + cnt.valor());
}
}
}
Práctica 1 - Programación Concurrente 3º I.S.
Pág: 3/15
classEjemploContador { // principal
final static int nHebras = 20;
public static void main(String[] args) { // metodo principal
Contador cont1 = new Contador(10);
Usuario hebra[] = new Usuario[nHebras];
for (int i = 0; i < nHebras; i++) {
hebra[i] = new Usuario("la hebra-" + i, cont1); //crea hebras
hebra[i].start(); // lanza hebras
}
}
}
2 Métodos de espera y notificación.
En Java no existe el concepto de variablecondición. Podríamos decir que cada monitor en
Java tiene una única variable condición anónima. Los monitores de Java implementan la disciplina
signal and continue.
Los métodos wait(), notify() y notifyAll() implementan los mecanismos de espera y
notificación de los monitores Java. Estos métodos solamente pueden ser llamados por una hebra
cuando ésta posee el cerrojo del objeto, es decir, desdeun bloque o un método sincronizado.
La invocación al método wait() provoca que la hebra actual se bloquee y sea colocada en
una cola de espera asociada al objeto monitor. El cerrojo del objeto es liberado, para que otras
hebras puedan ejecutar métodos del objeto. Sin embargo, otros cerrojos poseídos por la hebra
suspendida son retenidos por ésta.
La invocación al método notify() provoca que, si hayalguna hebra bloqueada en wait(), se
escoja una cualquiera de forma arbitraria, y se saque de la cola de wait() pasando ésta al estado
preparado. La hebra que invocó notify() seguirá ejecutándose dentro del monitor. La hebra
señalada deberá adquirir el cerrojo del objeto para poder ejecutarse. Esto significará esperar al
menos hasta que la hebra que invocó notify() libere el cerrojo, bien por...
Regístrate para leer el documento completo.