Diferencia entre revisiones de «Monitores»
(→Definición: corregidos errores ortográficos) |
|||
Línea 47: | Línea 47: | ||
Como vemos, los monitores se implementan con semáforos, son una abstracción de los mismos. | Como vemos, los monitores se implementan con semáforos, son una abstracción de los mismos. | ||
+ | |||
+ | == Ejemplo en Java == | ||
+ | |||
+ | Ejemplo de sincronización mediante monitores en el que 5 hilos modifican dos variables. El hilo principal va mostrando el contenido de las variables. Si quitamos la clausula synchronized podemos ver como las variables no se modifican a la vez. | ||
+ | |||
+ | <source lang="java"> | ||
+ | public class Principal { | ||
+ | public static void main(String[]args){ | ||
+ | Cont c=new Cont(); | ||
+ | for(int i=0;i<5;i++){ | ||
+ | new Hilo(c); | ||
+ | } | ||
+ | while(true){ | ||
+ | c.mostrar(); | ||
+ | try{ | ||
+ | Thread.sleep(20); | ||
+ | }catch(InterruptedException e){} | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | class Hilo extends Thread{ | ||
+ | static int i=0; | ||
+ | int h; | ||
+ | Cont c; | ||
+ | public Hilo(Cont c){ | ||
+ | this.setDaemon(true); | ||
+ | this.c=c; | ||
+ | h=i++; | ||
+ | this.start(); | ||
+ | } | ||
+ | public void run(){ | ||
+ | while(true){ | ||
+ | c.incrementar(); | ||
+ | //System.out.println("Ahora se está ejecutando el hilo "+h); | ||
+ | try{ | ||
+ | sleep(20); | ||
+ | }catch(InterruptedException e){ | ||
+ | |||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class Cont{ | ||
+ | int a=0; | ||
+ | int b=0; | ||
+ | synchronized public void incrementar(){ | ||
+ | a++; | ||
+ | b++; | ||
+ | } | ||
+ | public void mostrar(){ | ||
+ | System.out.println("a: "+a+"\tb: "+b); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </source> | ||
== Fuentes == | == Fuentes == | ||
<references/> | <references/> |
Revisión del 13:43 15 nov 2011
Idea desarrollada en los años 70 Brinch-Hansen y Hoare <ref>http://java.sun.com/developer/Books/performance2/chap4.pdf</ref>que notaron los siguientes problemas con respecto al uso de los semáforos:
- Los semáforos son difíciles de usar. Es frecuente que el programador cometa errores al emplearlos.
- El compilador no asiste al programador en el desarrollo de programas concurrentes mediante semáforos, pues no ofrece ningún tipo de validación en tiempo de compilación.
- No hay nada que obligue a usarlos. Puede suceder que el programador los necesite y lo desconozca
- Son independientes del recurso compartido
Los monitores tienen que estar integrados en el lenguaje de programación.
Definición
Un monitor es una estructura del lenguaje cuyas principales características son:
- Los datos son privados.
- Ofrecen una serie de métodos públicos para acceder a dichos datos.
- En cada momento sólo puede haber un proceso activo en algún método del monitor, es decir, ejecutando código de esos métodos públicos del monitor. Seria equivalente a decir que el recurso que queremos compartir se declara como monitor. Los procesos que usan el monitor son independientes unos de otros y cuando deseen usar el recurso, llamarán a los métodos del monitor que implementen la operación que se desea ejecutar.
Permiten organizar procesos en espera mediante:
- Variables de condición: lista de procesos inicialmente vacía.
- Primitivas: wait(c), añade el proceso p invocante a c y proceso p bloquea; signal(c), selecciona a uno de los procesos en c y lo pone en preparado.
class recursoCompartido {
public int get(void);
public void set(int valor);
private int recursoCompartido;
private Semaforo s = 1;
public int get(void){
int ret;
down(s);
ret = recursoCompartido;
up(s);
return ret;
}
public void set(int valor){
down(s);
recursoCompartido = valor;
up(s);
}
}
Como vemos, los monitores se implementan con semáforos, son una abstracción de los mismos.
Ejemplo en Java
Ejemplo de sincronización mediante monitores en el que 5 hilos modifican dos variables. El hilo principal va mostrando el contenido de las variables. Si quitamos la clausula synchronized podemos ver como las variables no se modifican a la vez.
public class Principal {
public static void main(String[]args){
Cont c=new Cont();
for(int i=0;i<5;i++){
new Hilo(c);
}
while(true){
c.mostrar();
try{
Thread.sleep(20);
}catch(InterruptedException e){}
}
}
}
class Hilo extends Thread{
static int i=0;
int h;
Cont c;
public Hilo(Cont c){
this.setDaemon(true);
this.c=c;
h=i++;
this.start();
}
public void run(){
while(true){
c.incrementar();
//System.out.println("Ahora se está ejecutando el hilo "+h);
try{
sleep(20);
}catch(InterruptedException e){
}
}
}
}
class Cont{
int a=0;
int b=0;
synchronized public void incrementar(){
a++;
b++;
}
public void mostrar(){
System.out.println("a: "+a+"\tb: "+b);
}
}
Fuentes
<references/>