Programacin Paralela y Concurrente Luis Alfredo Martinez Reyes Eduardo Jimene de la cruz Rafael Notario Rodriguez Francisco Romero Loeza Cern Garnica Carmen
Misioneros Barbero Dormilon Estacionamiento Filosofos Puente. Fumadores Bao mixto Lectores Escritores Congreso Carpintera
Introduccin: En la actualidad hay una gran variedad de problemas y en ocasiones la solucin de un problema en particular varia dependiendo de la complejidad del algoritmo que se desarrollo para la solucin del mismo. Aunado a esto hay que considerar las tecnologas que estn saliendo y que ayudan a la optimizacin de las soluciones de problemas que necesitan la aplicacin de la concurrencia o el paralelismo. Para ello tenemos que abordar tres conceptos en particular que son: las primitivas en Java, los Semforos y los Monitores en Java. Recordando que la complejidad de la solucin de problemas por medio de concurrencia en cuanto a primitivas se refiere es un medio simple para controlar el acceso al procesador mientras que en los semforos existe la sincronizacin que permite el control de mas procesos y con ciertas limitaciones en cuanto al numero de los procesos. Una alternativa para problemas que requieren el uso de muchos procesos y que permita el control mas rgido por medio de varias variables de control son los monitores, el cual Java te brinda varios paquetes para que el programador a nivel de usuario pueda manipular y moldear una solucin mejor en cuanto a complejidad y rapidez de la solucin se refiere. Problema de los Misioneros: Una tribu atrapo a 6 misioneros, los cuales se van a ir cocinando cuando tengan hambre los antropfagos, el cocinero se despertar cada vez que cocine a un misionero y dormir cuando estn comiendo los antropfagos. Solo puede cocinar uno solo en el cazo. Sincronizar cocinero, los misioneros y los antropfagos que deben de despertar al cocinero cada vez que tiene hambre.
import java.util.logging.Level; import java.util.logging.Logger; class Misioneros { public static void main(String[] args) { Olla ecko = new Olla(5); Cocinero chef = new Cocinero(ecko); Loco l = new Loco(ecko); chef.start(); l.start(); } }
class Cocinero extends Thread { public Olla olla; boolean ctrl; public Cocinero (Olla olla) { this.olla = olla; ctrl = true; } @Override public void run () { while (ctrl) { olla.cocinar(); try { sleep(30); } catch (InterruptedException ex) { } } } }
class Loco extends Thread { private Olla olla; boolean ctrl; public Loco (Olla olla) { this.olla = olla; ctrl = true; } @Override public void run () { while (ctrl) { olla.devorado(); try { sleep(30); } catch (InterruptedException ex) { } } } }
class Olla { private int misioneros; private boolean lleno; public Olla (int x) { misioneros = x;
lleno = true; } public synchronized boolean cocinar () { while (lleno==false) { System.out.println("Cocinando a un canibal, ..."); misioneros++; if (misioneros ==5){ System.out.println("ytytyytytyt"); lleno=true;} else{ //misioneros++; lleno=false; System.out.println("sjhjhf"); } notify(); } try { wait(); } catch (InterruptedException ex) { } // Espero a que lo coman System.out.println("//Sigo durmiendo..."); if (misioneros == 5) { notify(); return true; } else { notify(); return false; } } public synchronized boolean devorado () { while (misioneros==0) { // Mientras no haya misioneros listos System.out.println("Quiero comer, me espero"); lleno=false; //notify(); // Le digo al cocinero que saque uno de la olla try { wait(); } catch (InterruptedException ex) { } // Espero a que lo saque } System.out.println("Me comere uno..."); System.out.println("ME COMi A UN MISIONERO!!!!"); misioneros--; // Esperara al siguiente listo notify(); // Notifico que ya com if (misioneros == 0) { return false; } else return true; } }
public synchronized void disminuir(String Nombre) { while(entrada == true && contador <= 5){ try { wait(); } catch (InterruptedException e) { } }//while contador=contador-5; if(contador == 0) muebles++;
System.out.println( Nombre + "se llena =" + muebles +" veces la olla");//+Thread.currentThread().getName() entrada= true; //notify (); }//fin del mtodo sincronizado }// fin de clase
class Canibal1 extends Thread{ private Recurso_Compartido_Olla contar; private String Nombre; public Canibal1(Recurso_Compartido_Olla contar, String Nombre1){ this.contar=contar; this.Nombre=Nombre1; } public void run(){ try{sleep((int)(Math.random()*3000));}//fin_sleep catch(InterruptedException e){System.err.println("Error"+e.toString());}//fin_catch contar.aumentar(Nombre); } }//fin_hilo1
class Canibal2 extends Thread{ private Recurso_Compartido_Olla contar; private String Nombre; public Canibal2(Recurso_Compartido_Olla contar, String Nombre1){ this.contar=contar; this.Nombre=Nombre1; } public void run(){ try{sleep((int)(Math.random()*3000));}//fin_sleep catch(InterruptedException e){System.err.println("Error"+e.toString());}//fin_catch contar.aumentar(Nombre); } }//fin_hilo2
class Canibal3 extends Thread{ private Recurso_Compartido_Olla contar; private String Nombre; public Canibal3(Recurso_Compartido_Olla contar, String Nombre1){ this.contar=contar; this.Nombre=Nombre1; } public void run(){ try{sleep((int)(Math.random()*5000));}//fin_sleep catch(InterruptedException e){System.err.println("Error"+e.toString());}//fin_catch contar.aumentar(Nombre); } }//fin_hilo3
class Cocinero extends Thread{ private Recurso_Compartido_Olla contar; private String Nombre;
public Cocinero(Recurso_Compartido_Olla contar, String Nombre1){ this.contar=contar; this.Nombre=Nombre1; } public void run(){ //for(int i=1; i<=10; i++) contar.disminuir(Nombre); } }//fin_hilo3
public class Canibales_Primitivas { protected static final Recurso_Compartido_Olla contador= new Recurso_Compartido_Olla(); public static void main (String args[])throws IOException{
for(int i = 0;i<=10;i++){ Canibal1 contador1= new Canibal1(contador,"Canibal 1"); Canibal2 contador2= new Canibal2(contador,"Canibal 2"); Canibal3 contador3= new Canibal3(contador,"Canibal 3"); Cocinero contador4= new Cocinero(contador,"\n Despierta cocinero!!! \t Cocicero cicina \n"); contador1.start(); contador2.start(); contador3.start(); contador4.start(); }//for }//Main }//fin class Carpinteria_Primitivas
class Cliente extends Thread { private Barberia barberia; boolean ctrl; public Cliente (Barberia barberia) { this.barberia = barberia; ctrl = true;
} public void run () { while (ctrl) { barberia.solicitar(); try { sleep(30); } catch (InterruptedException ex) { } } } } class Barberia { private int clientes; private boolean lleno; private boolean vacio; public Barberia (int x) { clientes = x; lleno = false; } public synchronized boolean cortar () { while (vacio==false) { System.out.println("Atendiendo cliente"+clientes); clientes--; if (clientes ==0){ System.out.println("No hay clientes"); vacio=true;} else{ vacio=false; System.out.println("Aun hay clientes"); } notify(); } try { wait(); } catch (InterruptedException ex) { } System.out.println("//Sigo durmiendo..."); if (clientes == 10) { notify(); return true; } else { notify(); return false; } } public synchronized boolean solicitar () { while (clientes==0) { // Mientras no haya clientes System.out.println("Barbero dormido"); lleno=false; //notify(); // try { wait(); } catch (InterruptedException ex) { } } notify(); // Notifico que ya termino clietnte if (clientes == 0) {
10
try { sleep((int)(Math.random() * 50000)); // durante tiempo aleatorio } catch (InterruptedException e) { } System.out.println("Cliente " + i + " necesita un corte de cabello"); quiereCorte(); } } public void quiereCorte() { s.mutex.down(); if (s.esperar < s.numSillas) { s.esperar++; // uno o mas clientes esperando System.out.println("El Cliente " + i + " esta esperando en la sala. (Sillas ocupadas: " + s.esperar + "/" + s.numSillas + ")"); s.cliente.up(); // incremento cliente en espera s.mutex.up(); s.barbero.down(); // espera la silla del barbero System.out.println("Cliente " + i + " esta siendo atendido"); try { Thread.sleep((int)(Math.random() * 25000)); //tiempo que demora el corte } catch (InterruptedException e) { } System.out.println("Termina el corte para el Cliente " + i); s.cortar.up(); // termin el corte } else { System.out.println("Cliente " + i + " se retira, la sala esta llena"); s.mutex.up(); } } } class Salon { public int numSillas, esperar; public Semaphore cliente, barbero, cortar; public BinarySemaphore mutex; public Salon(int numSillas) { this.numSillas = numSillas; cliente = new Semaphore(0); barbero = new Semaphore(0); cortar = new Semaphore(0); mutex = new BinarySemaphore(1); } } class BarberoDurmiente { public static void main(String[] args) { int numSillas = 4; int numClientes = 10; Salon s = new Salon(numSillas); new Barbero(s).start(); for(int i = 0; i < numClientes; i++) new Cliente(s,i).start(); }
11
12
private Semaforo mon; public monitor() { mon = new Semaforo(1); } public void enter() { mon.WAIT(); } public void exit() { mon.SIGNAL(); } public condicion creaCond() { return new condicion(mon); } } //clase condicin class condicion{ private Semaforo cond, mon; private int waiting; public condicion(Semaforo mon) { cond = new Semaforo(0); this.mon = mon; waiting = 0; } public void WAIT() { waiting++; mon.SIGNAL(); cond.WAIT(); mon.WAIT(); } public void SIGNAL() { if(waiting> 0) { waiting--; } cond.SIGNAL(); } public void broadcast_cond() { for(; waiting> 0; waiting--) cond.SIGNAL(); } public boolean has_waiting() { return waiting> 0; } }
class carPark { condicion ticketExpedido; condicion Subirbarrera; condicion cocheHaPasado; condicion noHayCoche; condicion BajarBarrera; condicion numCoches; condicion boton; monitor mon; public carPark() {
13
mon = new monitor(); boton = mon.creaCond(); ticketExpedido = mon.creaCond(); Subirbarrera = mon.creaCond(); cocheHaPasado = mon.creaCond(); noHayCoche = mon.creaCond(); BajarBarrera = mon.creaCond(); numCoches = mon.creaCond(); noHayCoche.SIGNAL(); BajarBarrera.SIGNAL(); numCoches.SIGNAL(); } public void esperaPasar(int i) { try { Thread.sleep(1000); } catch(Exception e) {} mon.enter(); System.out.println("el coche "+i+" llego"); noHayCoche.WAIT(); BajarBarrera.WAIT(); boton.SIGNAL(); Subirbarrera.WAIT(); System.out.println("Coche: "+i+" entra"); cocheHaPasado.SIGNAL(); noHayCoche.SIGNAL(); mon.exit(); try { Thread.sleep(1000); } catch(Exception e) {} mon.enter(); numCoches.SIGNAL(); System.out.println("Salio Coche: "+i); mon.exit(); } public void pasaCoche() { while(true) { mon.enter(); numCoches.WAIT(); ticketExpedido.WAIT(); Subirbarrera.SIGNAL(); System.out.println("Subiendo Barra..."); cocheHaPasado.WAIT(); System.out.println("Bajando Barra..."); BajarBarrera.SIGNAL(); mon.exit(); } } public void expideTiket() { while(true) { mon.enter(); boton.WAIT(); System.out.println("Expidiendo ticket..."); ticketExpedido.SIGNAL(); mon.exit();
14
} } } class Coche extends Thread { int i; carPark e; public Coche(int _i, carPark e) { i = _i; this.e = e; } public void run() { e.esperaPasar(i); } } class MaquinaTikets extends Thread { carPark e; public MaquinaTikets(carPark e) { this.e = e; } public void run() { e.expideTiket(); } } class Barra extends Thread { carPark e; public Barra(carPark e) { this.e = e; } public void run() { e.pasaCoche(); } }
//programa principal parking con los procesos barra,maquinaTikets , coche public class parking { static carPark e; public static void main(String args[]) { int i; e = new carPark(); Coche coches[] = new Coche[10]; MaquinaTikets maquina = new MaquinaTikets(e); Barra barra = new Barra(e); for(i=0; i<10; i++) coches[i] = new Coche(i,e); for(i=0; i<10; i++) coches[i].start(); maquina.start(); barra.start(); } }
15
{ i=_i; } @Override public void run () { try {Thread.sleep (1000);} catch (Exception e) {} System.out.println ("llega el coche"+i); noHayCoche.WAIT(); barreraBajada.WAIT(); boton.Signal(); barreraAbierta.WAIT(); System.out.println ("coche: "+i+" pasado"); cocheHaPasado.Signal(); noHayCoche.Signal(); try { Thread.sleep (1000);} catch (Exception e) {} numCoches.Signal(); System.out.println ("Coche:"+i+" saliendo"); } } public class Comun { protected static SemaforoBinario boton = new SemaforoBinario(0); protected static SemaforoBinario ticketExpendido =new SemaforoBinario(0); protected static SemaforoBinario barreraAbierta=new SemaforoBinario(0); protected static SemaforoBinario cocheHaPasado=new SemaforoBinario(0); protected static SemaforoBinario noHayCoche=new SemaforoBinario(1); protected static SemaforoBinario barreraBajada=new SemaforoBinario(1); protected static SemaforoGeneral numCoches=new SemaforoGeneral(5); } public class Maquina extends Comun implements Runnable { @Override public void run () { while (true) { boton.WAIT(); System.out.println("EXPENDIENDO TICKET"); ticketExpendido.Signal(); } } } public class SemaforoBinario { protected int contador =0; public SemaforoBinario (int valorInicial) { contador = valorInicial; } synchronized public void WAIT () { while (contador ==0) { try { wait(); } 17
catch (Exception e){} } contador--; } synchronized public void Signal () { contador=1; notify(); } } public class SemaforoGeneral extends SemaforoBinario { public SemaforoGeneral (int valorInicial) { super (valorInicial); } synchronized public void SIGNAL () { contador++; notify(); } }
18
19
class llenar extends Thread { private terminal term; public llenar (terminal r) { this.term = r; } @Override public void run() { for (int i=0; i<=39; i++) { // control de pasajeros term.entra (new Integer(i)); System.out.println ("El pasajero " + i + " llega a la terminal."); try { sleep ((int)(Math.random() * 300)); } catch (InterruptedException e) {} } } } class vaciar extends Thread { private terminal termin; public vaciar (terminal r) { this.termin = r; } int i = 0; @Override public void run() { while (i <= 3) { termin.salida(); System.out.println ("El camion " + i + " ha salido con 10 personas."); i++; } } } class terminal { private boolean lleno = false; private ColaEnlazada tail = new ColaEnlazada(); public synchronized void salida() { while (!lleno) { try { wait(); } catch (InterruptedException e) {} } tail.Vaciar(); lleno = false; notify(); }
20
public synchronized void entra (Object o) { if (tail.Size() != 10) { while (lleno) { try { wait(); } catch (InterruptedException e) {} } tail.Insertar(o); } else { lleno = true; notify(); } } } class ColaEnlazada { Nodo frente, fondo; int size; public ColaEnlazada () { frente = null; fondo = null; size = 0; } int Size () { return size; } boolean isEmpty () { if (size == 0) { return true; } else { return false; } } void Vaciar () { frente = null; fondo = null; size = 0; } void Insertar (Object o) { Nodo temp = new Nodo(); temp.setInfo (o); if (isEmpty()) { frente = temp; fondo = temp; } else { fondo.setProx (temp); fondo = temp;
21
} size ++; } Object Extraer () { Object info; info = frente.getProx(); frente = frente.getProx(); size--; return info; } } class Nodo { private Object info; private Nodo prox; Nodo() { info = null; prox = null; } void setInfo (Object o) { info = o; } void setProx (Nodo temp) { prox = temp; } Object getInfo() { return info; } Nodo getProx() { return prox; } } public class Barrera extends Comun implements Runnable { public void run () { while (true) { numCoches.WAIT(); ticketExpendido.WAIT(); barreraAbierta.Signal(); System.out.println ("Levantando barrera"); cocheHaPasado.WAIT(); System.out.println ("Bajando barrera"); barreraBajada.Signal(); } } } public class Coche extends Comun implements Runnable { int i;
22
public Coche(int _i) { i=_i; } public void run () { try {Thread.sleep (1000);} catch (Exception e) {} System.out.println ("llega el coche"+i); noHayCoche.WAIT(); barreraBajada.WAIT(); boton.Signal(); barreraAbierta.WAIT(); System.out.println ("coche: "+i+" pasado"); cocheHaPasado.Signal(); noHayCoche.Signal(); try { Thread.sleep (1000);} catch (Exception e) {} numCoches.Signal(); System.out.println ("Coche:"+i+" saliendo"); } } public class Comun { protected static SemaforoBinario boton = new SemaforoBinario(0); protected static SemaforoBinario ticketExpendido =new SemaforoBinario(0); protected static SemaforoBinario barreraAbierta=new SemaforoBinario(0); protected static SemaforoBinario cocheHaPasado=new SemaforoBinario(0); protected static SemaforoBinario noHayCoche=new SemaforoBinario(1); protected static SemaforoBinario barreraBajada=new SemaforoBinario(1); protected static SemaforoGeneral numCoches=new SemaforoGeneral(5); } public class Maquina extends Comun implements Runnable { public void run () { while (true) { boton.WAIT(); System.out.println("EXPENDIENDO TICKET"); ticketExpendido.Signal(); } } } public class Parking { public static void main (String args[]) { for (int i=0;i<10;i++) { new Thread (new Coche(i)).start(); } new Thread (new Maquina()).start(); new Thread (new Barrera()).start(); }
23
24
} catch (Exception e){} } contador--; } synchronized public void Signal () { contador=1; notify(); } } public class Autobus { public static void main(String args[]) { terminal t = new terminal(); llenar l = new llenar(t); vaciar v = new vaciar(t); l.start(); v.start(); } } class llenar extends Thread { private terminal term; public llenar (terminal r) { this.term = r; } @Override public void run() { for (int i=0; i<=39; i++) { // control de pasajeros term.entra (new Integer(i)); System.out.println ("El pasajero " + i + " llega a la terminal."); try { sleep ((int)(Math.random() * 300)); } catch (InterruptedException e) {} } } } class vaciar extends Thread { private terminal termin; public vaciar (terminal r) { this.termin = r; } int i = 0; @Override public void run() { while (i <= 3) {
25
termin.salida(); System.out.println ("El camion " + i + " ha salido con 10 personas."); i++; } } } class terminal { private boolean lleno = false; private ColaEnlazada tail = new ColaEnlazada(); public synchronized void salida() { while (!lleno) { try { wait(); } catch (InterruptedException e) {} } tail.Vaciar(); lleno = false; notify(); } public synchronized void entra (Object o) { if (tail.Size() != 10) { while (lleno) { try { wait(); } catch (InterruptedException e) {} } tail.Insertar(o); } else { lleno = true; notify(); } } } class ColaEnlazada { Nodo frente, fondo; int size; public ColaEnlazada () { frente = null; fondo = null; size = 0; } int Size () { return size; } boolean isEmpty () { if (size == 0) { return true;
26
} else { return false; } } void Vaciar () { frente = null; fondo = null; size = 0; } void Insertar (Object o) { Nodo temp = new Nodo(); temp.setInfo (o); if (isEmpty()) { frente = temp; fondo = temp; } else { fondo.setProx (temp); fondo = temp; } size ++; } Object Extraer () { Object info; info = frente.getProx(); frente = frente.getProx(); size--; return info; } } class Nodo { private Object info; private Nodo prox; Nodo() { info = null; prox = null; } void setInfo (Object o) { info = o; } void setProx (Nodo temp) { prox = temp; } Object getInfo() { return info; } Nodo getProx() { return prox;
27
} } public class Barrera extends Comun implements Runnable { public void run () { while (true) { numCoches.WAIT(); ticketExpendido.WAIT(); barreraAbierta.Signal(); System.out.println ("Levantando barrera"); cocheHaPasado.WAIT(); System.out.println ("Bajando barrera"); barreraBajada.Signal(); } } } public class Coche extends Comun implements Runnable { int i; public Coche(int _i) { i=_i; } public void run () { try {Thread.sleep (1000);} catch (Exception e) {} System.out.println ("llega el coche"+i); noHayCoche.WAIT(); barreraBajada.WAIT(); boton.Signal(); barreraAbierta.WAIT(); System.out.println ("coche: "+i+" pasado"); cocheHaPasado.Signal(); noHayCoche.Signal(); try { Thread.sleep (1000);} catch (Exception e) {} numCoches.Signal(); System.out.println ("Coche:"+i+" saliendo"); } } public class Comun { protected static SemaforoBinario boton = new SemaforoBinario(0); protected static SemaforoBinario ticketExpendido =new SemaforoBinario(0); protected static SemaforoBinario barreraAbierta=new SemaforoBinario(0); protected static SemaforoBinario cocheHaPasado=new SemaforoBinario(0); protected static SemaforoBinario noHayCoche=new SemaforoBinario(1); protected static SemaforoBinario barreraBajada=new SemaforoBinario(1); protected static SemaforoGeneral numCoches=new SemaforoGeneral(5);
28
} public class Maquina extends Comun implements Runnable { public void run () { while (true) { boton.WAIT(); System.out.println("EXPENDIENDO TICKET"); ticketExpendido.Signal(); } } } public class Parking { public static void main (String args[]) { for (int i=0;i<10;i++) { new Thread (new Coche(i)).start(); } new Thread (new Maquina()).start(); new Thread (new Barrera()).start(); } }
29
30
{ return i; } } //clase Tenedor class Tenedor { private int identidad; private boolean cogido; public Tenedor (int identidad) { this.identidad= identidad; } synchronized public void coger() { if (cogido) { System.out.println (" -Tenedor " + identidad + ": SE ESTAN PELEANDO POR MI!"); System.exit(1); } else { cogido= true; System.out.println (" -Tenedor " + identidad + " ha sido tomado"); } } synchronized public void soltar() { cogido= false; System.out.println (" -Tenedor " + identidad + " ha sido soltado"); } } //clase Filosofo class Filosofo implements Runnable { private Thread t; protected Mesa mesa; protected int ind_izq, ind_der; protected int identidad; public Filosofo (int identidad, Mesa mesa) { this.identidad= identidad; this.mesa= mesa; ind_izq= mesa.mi_tenedor_izquierdo(identidad); ind_der= mesa.mi_tenedor_derecho(identidad); t= new Thread(this); t.start(); } protected void pensar() { try { System.out.println ("Filosofo " + identidad + " esta pensando"); int delay= (int)(Math.random()*1000); t.sleep(delay); System.out.println ("Filosofo " + identidad + " ha dejado de pensar");
31
} catch (InterruptedException e) {} } protected void comer() { try { System.out.println ("Filosofo " + identidad + " esta comiendo"); int delay= (int)(Math.random()*1000); t.sleep(delay); System.out.println ("Filosofo " + identidad + " ha terminado de comer"); } catch (InterruptedException e) {} } protected void protocolo_entrada() { System.out.println ("Protocolo antiguo"); Tenedor tizq= mesa.tenedor(ind_izq); Tenedor tder= mesa.tenedor(ind_der); tizq.coger(); tder.coger(); } protected void protocolo_salida() { Tenedor tizq= mesa.tenedor(ind_izq); Tenedor tder= mesa.tenedor(ind_der); tizq.soltar(); tder.soltar(); } public void run() { while (true) { pensar(); protocolo_entrada(); comer(); protocolo_salida(); } } } // Principal class Filosofos { public static void main (String args[]) { int comensales=5; System.out.println ("Poniendo la mesa para " + comensales + " comensales"); Mesa mesa= new Mesa(comensales); System.out.println ("Creando a los filosofos y sentandolos a la mesa"); for (int i= 0; i<comensales; i++) { Filosofo f= new Filosofo(i, mesa); } } }
32
33
losPalillos.dejar(Id); } } } class Palillos { final int NP=5; private int PalillosDisp[] = new int[NP]; public Palillos() { for(int j=0; j<NP;j++) PalillosDisp[j]=2; } public synchronized void coger(int i) { while(PalillosDisp[i]!=2) { try { wait(); } catch(InterruptedException e) {} } PalillosDisp[ (i+(NP-1)) % NP ] -= 1; PalillosDisp[ (i+1) % NP ] -= -1; System.out.println("Comiendo filsofo "+ i); } public synchronized void dejar(int i) { PalillosDisp[ (i+(NP-1)) % NP ] += 1; PalillosDisp[ (i+1) % NP ] += -1; System.out.println("Filsofo "+ i +" a pensar"); if ( PalillosDisp[ (i+(NP-1)) % NP ] == 2 || PalillosDisp[ (i+1) % NP ] == 2) notifyAll(); } } public class laCena { public static void main(String arg[]) { Palillos p = new Palillos(); Filosofo f[] = new Filosofo[5]; for(int i=0;i<5;i++) { f[i]=new Filosofo( i, p ); f[i].start(); } } }
34
import java.util.concurrent.locks.*; class CochesOeste extends Thread { Puente puente; public CochesOeste(Puente p_puente) { puente = p_puente; } public void run() { try { puente.entrarCocheOeste(); //tratar de pasar x el puente System.out.println("ENTRO "+getName()); //PASAR EL PUENTE sleep(200); puente.salirCocheOeste(); System.out.println("SALIO "+getName()); } catch (InterruptedException e) { } } } class CochesEste extends Thread { Puente puente; public CochesEste(Puente p_puente) { puente = p_puente; } public void run() { try { puente.entrarCocheEste(); //tratar de pasar x el puente System.out.println("ENTRO "+getName()); //PASAR EL PUENTE sleep(100); puente.salirCocheEste(); System.out.println("SALIO "+getName()); } catch (InterruptedException e) { } } }
class Puente { final ReentrantLock cerrojo = new ReentrantLock(); final Condition okCocheE = cerrojo.newCondition(); final Condition okCocheO = cerrojo.newCondition(); int c,b;
36
public Puente() { b=0; c=0; } public void entrarCocheEste() throws InterruptedException { cerrojo.lock(); try { while ((b>0)) { System.out.println("coche del Este esperando..puente ocupado"); okCocheE.await(); //el coche espera } c++; //--incrementa el nmero de coches pasando okCocheE.signal(); //--despierta si hay otro coche esperando //BAJAR PUENTE } finally { cerrojo.unlock(); } } public void salirCocheEste() throws InterruptedException { cerrojo.lock(); try { System.out.println("coche del ESTE saliendo..puente libre"); c--; //--disminuye el nro. de coches pasando if (c==0) okCocheO.signal(); //--el ltimo coche que pasa //--comunica al cohe que puede pasar (si //--hubiera) } finally { cerrojo.unlock(); } } public void entrarCocheOeste() throws InterruptedException { cerrojo.lock(); try { while ((c>0)) //--si hay coches pasando { System.out.println("Coche del OESTE esperando..puente ocupado"); okCocheO.await(); //--esperar a que pasen los coches } b++; //--incrementa el no. de coches pasando okCocheO.signal(); //--despierta a otro coche si hubiera //--para que intente pasar } finally {
37
cerrojo.unlock(); } } public void salirCocheOeste() throws InterruptedException { cerrojo.lock(); try { System.out.println("Coche del OESTE saliendo..puente libre"); b--; //--disminuye el num. decoches pasando if(b==0) okCocheE.signal(); //-- el ltimo coche comunica al coche //--que espera (si hubiera) que puede intentar pasar } finally { cerrojo.unlock(); } } private int awaited(Condition condicion) { //--devuelve el nmero de hilos que esperan sobre la variable condicion return cerrojo.getWaitQueueLength(condicion); } } public class Carretera { public static void main(String arg[]) { boolean carrera=true; int lap=1; //--CREAR EL MONITOR while( carrera==true){ Puente puente = new Puente(); //--CREAR LOS HILOS A LOS QUE SE PASA COMO PARAMETRO EL MONITOR A UTILIZAR CochesEste c1 = new CochesEste(puente); CochesOeste b1 = new CochesOeste(puente); CochesEste c2 = new CochesEste(puente); CochesOeste b2 = new CochesOeste(puente); CochesEste c3 = new CochesEste(puente); CochesOeste b3 = new CochesOeste(puente); CochesEste c4 = new CochesEste(puente); CochesOeste b4 = new CochesOeste(puente); CochesEste c5 = new CochesEste(puente); CochesOeste b5 = new CochesOeste(puente); //--PONER NOMBRE A LOS HILOS //inicia la carrera c1.setName("CocheEste 01\n"); c2.setName("CocheEste 02\n"); c3.setName("CocheEste 03\n"); c4.setName("CocheEste 04\n"); c5.setName("CocheEste 05\n"); b1.setName("CocheOeste 06\n"); b2.setName("CocheOeste 07\n"); b3.setName("CocheOeste 08\n"); b4.setName("CocheOeste 09\n"); b5.setName("CocheOeste 10\n");
38
//--EJECUTAR LOS HILOS try { c1.start(); b1.start(); c2.start(); b2.start(); c3.start(); b3.start(); c4.start(); b4.start(); c5.start(); b5.start(); lap++; if(lap>=5){ carrera=false;} Thread.sleep(3000); }catch (InterruptedException e) { } } } }
39
40