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:
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
	 * &egrave; 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);
        }
    }   
}
scusa te x la lunghezza del codice, ma sono disperato, nn riesco a trovare l'errore, mi dice 'Exception in thread "main"'!!