ciao a tutti.
ho un problema, devo fare un elaborato in java per risolvere un problema di concorrenza il testo è il seguente: 'Nella stazione di Peggiodicosì c’è un bagno solo che può essere condiviso da uomini e da donne ma non contemporaneamente.'; devo risolvere il problema con i monitor.
il codice è questo:scusa te x la lunghezza del codice, ma sono disperato, nn riesco a trovare l'errore, mi dice 'Exception in thread "main"'!!codice:import java.io.*; import java.lang.Thread; /** * Classe Urgent per sospensione dei processi che eseguono la Signal. */ class Urgent { private int n_sig = 0; // tiene conto di notify per processi che non hanno ancora fatto la wait private Monitor mon; /** * Costruttore della classe Urgent; * * @param mon il monitor in cui la variabile urgent * è definita. */ public Urgent(Monitor mon) { this.mon = mon; } /** Sospende sulla coda Urgent (a seguito di una signal sospensiva su una var condizione). */ synchronized public void Wait() { if (n_sig == 0) try{ wait(); } catch(InterruptedException e){} n_sig--; mon.urgentCount--; } /** Risveglia un processo sospeso sulla urgent. */ synchronized public void Signal() { notify(); n_sig++; } } /** * Classe Monitor. * */ class Monitor { Mutex mutex = new Mutex(); Urgent urgentQueue = new Urgent(this); int urgentCount = 0; /** * Costruttore della classe Monitor */ public Monitor() { } /** * Da invocare come prima istruzione di una procedure entry; * permette di acquisire il monitor */ protected void entraMonitor() { mutex.Wait(); } /** * Da invocare come ultima istruzione di una procedure entry; * permette di rilasciare il monitor */ protected void esciMonitor() { if (urgentCount > 0) { // System.out.println(Thread.currentThread()+"esco dal monitor e signal su urgent"); urgentQueue.Signal(); } else { // System.out.println(Thread.currentThread()+"esco dal monitor e signal su mutex"); mutex.Signal(); } } } /** * Classe Mutex per garantire la mutua esclusione. */ class Mutex { private boolean occupato = false; /** Sospende il processo se la risorsa è occupata. */ synchronized public void Wait() { if (occupato) try{ wait(); } catch(InterruptedException e){} occupato = true; } /** Rilascia la risorsa e risveglia un processo sospeso. */ synchronized public void Signal() { occupato = false; notify(); } } /** * Classe che implementa una variabile condizione. */ class Cond { Monitor mon; int condCount; /** * Costruttore della classe Cond; * * tipicamente una variabile condition viene istanziata in da un oggetto monitor in questo modo: * <code>Cond c = new Cond(this);<code> * * @param mon il monitor in cui la variabile condizione * è definita. */ public Cond(Monitor mon){ this.mon = mon; } /** * Wait sulla variabile condizione, prima della sospensione rilascia il Mutex sul Monitor. */ synchronized public void Wait() { condCount ++; if (mon.urgentCount > 0) { // System.out.println(Thread.currentThread()+"processi in urgent: ne sveglio uno"); mon.urgentQueue.Signal(); } else { // System.out.println(Thread.currentThread()+"NO processi in urgent: signal su mutex"); mon.mutex.Signal(); } try{ wait(); } catch(InterruptedException e){} Thread.currentThread().yield(); condCount --; } synchronized private boolean SignalNascosta() { if (condCount > 0) { // System.out.println(Thread.currentThread()+"processi in condCount: ne sveglio uno"); mon.urgentCount++; notify(); return true; } else return false; } /** * Signal sulla variabile condizione: risveglia un processo sospeso * e sospende il segnalante sulla Coda Urgent. */ public void Signal() { // System.out.println(Thread.currentThread()+"chiamo la signal nascosta"); if (SignalNascosta()) { // System.out.println(Thread.currentThread()+"ho risvegliato: mi sospendo su urgent"); mon.urgentQueue.Wait(); // System.out.println(Thread.currentThread()+"sono stato risvegliato dalla urgent"); } } /** * Verifica la presenza di processi sospesi sulla Variabile Condizione. * @return ritorna true se ci sono processi sospesi, false altrimenti */ synchronized public boolean queue() { if (condCount > 0) return true; else return false; } } class Man extends Thread //Thread uomo { Bagno bagno; Man(Bagno bagno) { this.bagno=bagno; this.start(); } public void run() { while(true) { int time; time=(int)(((20000*Math.random ())+1)/2); try { this.sleep(time); } catch(Exception a){} ManIn(); System.out.println("\n---------------------------------------"); System.out.println("\n Uomo dentro il bagno"); System.out.println("\n Uomini in bagno: "+bagno.MenIn); System.out.println("\n Donne in attesa: "+bagno.WomenWaiting); System.out.println("\n Donne in bagno: "+bagno.WomenIn); System.out.println("\n---------------------------------------"); ManOut(); } } private void ManIn() //Entra in bagno { bagno.entraMonitor(); boolean in=false; while(in!=true) { if(bagno.free==2) //Se libero=2, allora il bagno è occupato dalle donne! { bagno.MenWaiting++; bagno.esciMonitor(); bagno.Men.Wait(); } else { bagno.free=1; //libero = uomo bagno.MenIn++; if(bagno.MenIn>5) { while(bagno.MenIn>0) { bagno.MenIn--; bagno.free=2; bagno.Women.Signal(); bagno.Men.Wait(); } } in=true; bagno.esciMonitor(); } } } private void ManOut() //Esce dal bagno ! { bagno.entraMonitor(); if(bagno.MenIn>0) { bagno.MenIn--; } if(bagno.MenIn==0) //Se libero=0, allora il bagno è libero! { bagno.free=0; while(bagno.WomenWaiting>0) { bagno.WomenWaiting--; bagno.Women.Signal(); } } bagno.esciMonitor(); } } class Woman extends Thread //Thread donna { Bagno bagno; Woman(Bagno bagno) { this.bagno=bagno; this.start(); } public void run() { while(true) { int time; time=(int)(((20000*Math.random ())+1)/2); try { this.sleep(time); } catch(Exception a){} WomanIn(); System.out.println("\n---------------------------------------"); System.out.println("\n Donna dentro il bagno"); System.out.println("\n Donne in bagno: "+bagno.WomenIn); System.out.println("\n Uomini in attesa: "+bagno.MenWaiting); System.out.println("\n Uomini in bagno: "+bagno.MenIn); System.out.println("\n---------------------------------------"); WomanOut(); } } private void WomanIn() //Entra in bagno { bagno.entraMonitor(); boolean in=false; while(in!=true) { if(bagno.free==1) //Se libero=1, allora il bagno è occupato dagli uomini! { bagno.WomenWaiting++; bagno.esciMonitor(); bagno.Women.Wait(); } else { bagno.free=2; //libero = donna bagno.WomenIn++; if(bagno.WomenIn>5) { while(bagno.WomenIn>0) { bagno.WomenIn--; bagno.free=1; bagno.Men.Signal(); bagno.Women.Wait(); } } in=true; bagno.esciMonitor(); } } } private void WomanOut() //Esce dal bagno { bagno.entraMonitor(); if(bagno.WomenIn>0) { bagno.WomenIn--; } if(bagno.WomenIn==0) { bagno.free=0; //Se libero=0, allora il bagno è libero! while(bagno.MenWaiting>0) { bagno.MenWaiting--; bagno.Men.Signal(); } } bagno.esciMonitor(); } } class Bagno extends Monitor //Classe bagno condivisa dai thread { public int free; public int MenWaiting; public int MenIn; public Cond Men; public int WomenWaiting; public int WomenIn; public Cond Women; int limite=0; Bagno(int MenWaiting,int MenIn,Cond Men,int WomenWaiting,int WomenIn,Cond Women,int free) { this.free=free; this.MenWaiting=MenWaiting; this.MenIn=MenIn; this.Men=Men; this.WomenWaiting=WomenWaiting; this.WomenIn=WomenIn; this.Women=Women; } } public class Es1 { public static void main (String[] args) { int NM=8; int NW=11; Monitor monitor=new Monitor(); //monitor Cond ManCondition=new Cond(monitor); //condition uomo Cond WomanCondition=new Cond(monitor); //condition donna Bagno bagno=new Bagno(0,0,ManCondition,0,0,WomanCondition,0); //bagno Man[] AMen=new Man[NM]; //array di uomini Woman[] AWomen=new Woman[NW]; //arrya di donne for(int i=0;i<NM;i++) //Crea i thread uomimi { AMen[i]=new Man(bagno); } for(int i=0;i<NW;i++) //Crea i thread donne { AWomen[i]=new Woman(bagno); } } }