Anda di halaman 1dari 40

Benemrita Universidad Autnoma de Puebla

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.

Solucin utilizando Monitores.


2

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; } }

}} Solucin utilizando Primitivas.


import java.io.*; class Recurso_Compartido_Olla { private int contador,muebles = 0; private boolean entrada=true; public Recurso_Compartido_Olla(){ contador=0; } public synchronized void aumentar(String Nombre) { while(entrada == false || contador >= 5 ){//, || try { wait(); } catch (InterruptedException e) { } }//while contador++; if(contador >= 5) entrada=false; System.out.println(Nombre + "se come ->" + contador +" misionero"); //entrada= true; notify (); }//fin del mtodo sincronizado

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

Problema del Barbero Dormilon:


En una barbera existe solamente 3 lugares para cortar cabello, barba y demas, y en la sala de espera cabe asta 6 personas. El barbero puede cortar solamente a uno, si los asientos estn llenos(3) el cliente debe de esperar en la sala de espera, pero hay ocasiones en la que los clientes se van, cada cliente consume alrededor de 50 minutos y la barberia se habre de 9 a 7 de la noche. Sincronice a los clientes y al barbero y diga cuantos clientes puede tener a da.

Solucin utilizando Monitores.


import java.util.logging.Level; import java.util.logging.Logger; class ProbBarberia { public static void main(String[] args) { Barberia B1 = new Barberia(10); Barbero b1 = new Barbero(B1); Cliente C1 = new Cliente(B1); b1.start(); C1.start(); } } class Barbero extends Thread { public Barberia barberia; boolean ctrl; public Barbero (Barberia barberia) { this.barberia = barberia; ctrl = true; } public void run () { while (ctrl) { barberia.cortar(); try { sleep(30); } catch (InterruptedException ex) { } } } }

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) {

return false; } else return true; } }

Solucin utilizando Semforos.


class Barbero extends Thread { private Salon s; public Barbero(Salon s) { this.s = s; } public void run() { while (true) quiereCortar(); } public void quiereCortar() { System.out.println("Barbero libre esperando por un cliente"); s.cliente.down(); // esperando un cliente. s.mutex.down(); //silla libre s.esperar--; // decrementa cola de cliente s.barbero.up(); // pemirte al siguiente cliente System.out.println("Cliente Sentado (Sillas ocupadas: " + s.esperar + "/" + s.numSillas + ")"); s.mutex.up(); // silla ocupada System.out.println("Barbero cortando cabello"); s.cortar.down(); // cortando } } class Cliente extends Thread { private Salon s; private int i; public Cliente(Salon s, int i) { this.s = s; this.i = i; } public void run() { while (true) { // System.out.println("Cliente " + i + " ");

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

Problema del Estacionamiento:


Un estacionamiento tiene 20 cajones, el coche llega y se le expide un ticket y en ese momento se levanta la pluma, el coche pasa y despues se baja la pluma y se estaciona el coche, de esta forma el estacionamiento se puede llnar y cuando este lleno debe de decir estacionamiento lleno, espere. Tambin los coches pueden salir. Hay que sincronizar que no pase 2 o mas coches por ticket ya sea para entrar o salir. Tambin hay que sincronizar que cuando est lleno ya no dejen entrar mas coches.

Solucin utilizando Monitores.


class Semaforo { protected int contador = 0; public Semaforo (int valorInicial) { contador = valorInicial; } synchronized public void WAIT () { while (contador == 0) try { wait(); } catch (Exception e) {} contador--; } synchronized public void SIGNAL () { contador = 1; notify(); } } //clase Monitor class monitor {

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

Solucin utilizando Semaforos.


public class SemParking { 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(); } } public class Barrera extends Comun implements Runnable { @Override 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) 16

{ 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

Solucin utilizando Primitivas.


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(); } }

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

Solucin utilizando Semaforos.


public class SemaforoGeneral extends SemaforoBinario { public SemaforoGeneral (int valorInicial) { super (valorInicial); } synchronized public void SIGNAL () { contador++; notify(); } } public class SemaforoBinario { protected int contador =0; public SemaforoBinario (int valorInicial) { contador = valorInicial; } synchronized public void WAIT () { while (contador ==0) { try { wait();

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

Problema de los Filosofos:


Existen 5 filosofos los cuales comen si tiene 2 cubiertos y cuando no comen estan pensando, solamente hay 4 tenedores, hay que considerar que si un filosofo esta mucho tiempo sin comer se muere por omicin de alimentos.

Solucin utilizando Monitores.


class Semaforo { private int contador; public Semaforo (int inicial) { contador= inicial; } public Semaforo () { contador= 0; } public synchronized void subir() { contador++; notifyAll(); } public synchronized void bajar() { try { while(contador == 0) wait(); } catch (InterruptedException e){}; contador--; } } //clase Mesa class Mesa { private Tenedor tenedores[]; private int comensales; public Mesa (int comensales) { this.comensales= comensales; tenedores= new Tenedor[comensales]; for (int i= 0; i < comensales; i++) tenedores[i]= new Tenedor(i); } public Tenedor tenedor(int i) { return tenedores[i]; } public int mi_tenedor_derecho(int i) { return (i+1)%comensales; } public int mi_tenedor_izquierdo(int i)

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

Solucin utilizando Semforos.


class Filosofo extends Thread { int Id; Palillos losPalillos; public Filosofo( int i, Palillos pal ) { Id = i; losPalillos = pal; } public void run() { // comeremos 5 veces for (int j=1; j<=5;j++) { // pensando try { sleep(1000); } catch(InterruptedException e) {} // A comer losPalillos.coger(Id); // Comiendo try { sleep(1000); } catch(InterruptedException e) {} // A pensar

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

Problema del Puente:


El pueblo de Puente Duero debe su nombre a un viejo puente romano sobre el conocido ro. El puente es estrecho y no permite el cruce de dos coches que circulen en sentidos contrarios. Por su peculiar forma, alto en el centro y bajo en los extremos, no hay visibilidad, y desde un lado no podemos saber si hay un coche empezando a cruzar el puente por el otro. Se han instalado cuatro sensores y dos barreras. Dos sensores indican la llegada de coches en cada direccin, emitiendo una seal por cada coche que pasa, y los otros dos indican salidas respectivas. Las barreras bloquean las entradas al puente, y cuando reciben una seal se levantan para permitir el paso de un coche (y uno slo), acto seguido se vuelven a cerrar.

Solucin utilizando Monitores.


35

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

Solucin utilizando Semforos

40

Anda mungkin juga menyukai