import monitor.*; //******************************************************************************/ // definizione di una classe che estende Monitor / //******************************************************************************/ public class MonitorStazione extends Monitor { /* Numero di passeggeri minimo e massimo */ public static final int MAX=10; public static final int MIN=2; /* Definisco le stazioni */ public static final int A=0; public static final int B=1; // ******************************************************************************/ // dichiarazione delle variabili di stato del Monitor / // ******************************************************************************/ private int nTreni; // numero dei treni a disposizione private int[] n_passeggeri; // numero di passeggeri per ogni treno private int[] treno_fermo; // il numero del treno presente in una delle due stazioni private int[] contPasseggeri; // contatore dei passeggeri sospesi sul binario di ogni stazione // ******************************************************************************/ // dichiarazione di variabili condition del Monitor / // ******************************************************************************/ Cond[] attesaTreno; // coda su cui attendono i passeggeri in attesa sul binario Cond[] attesaPasseggeri; // coda su cui attendono i treni arrivati al binario Cond[] codaViaggio; // coda su cui attendono i passeggeri entrati nel treno Cond[] attesaBinario; // coda su cui attendono i treni in attesa del binario // ******************************************************************************/ // costruttore e inizializzazione delle variabili di stato del Monitor / // ******************************************************************************/ public MonitorStazione(int treni) { nTreni=treni; contPasseggeri=new int[2]; attesaTreno = new Cond[2]; treno_fermo=new int[2]; attesaPasseggeri = new Cond[2]; attesaBinario = new Cond[2]; n_passeggeri = new int[nTreni]; codaViaggio = new Cond[nTreni]; for(int i=0; i=0)?" "+treno_fermo[0]+"("+n_passeggeri[treno_fermo[0]]+") ":" ")+ " "+((treno_fermo[1]>=0)?" "+treno_fermo[1]+"("+n_passeggeri[treno_fermo[1]]+") ":" ")+" "); System.out.println(); } // ******************************************************************************/ // dichiarazione e definizione delle procedure di Entry sul Monitor / // ******************************************************************************/ // Utilizzato dai passeggeri public void entraTreno(int stazione, int treno) { // come prima istruzione bisogna invocare entraMonitor entraMonitor(); System.out.println(Thread.currentThread().getName()+": devo prendere il treno n"+treno); stampaStato(); //qui non viene ancora conteggiato il passeggero appena "creato" while( (treno_fermo[stazione]!=treno)|| // se il treno fermo non quello che aspetto (n_passeggeri[treno]==MAX)) // se il treno pieno { System.out.println(Thread.currentThread().getName()+": mi sospendo in attesa del treno "+treno); if(n_passeggeri[treno]==MAX) System.out.println("perch il treno pieno"); contPasseggeri[stazione]++; attesaTreno[stazione].Wait(); contPasseggeri[stazione]--; stampaStato(); } //in stazione c' il mio treno e c' ancora posto System.out.println(Thread.currentThread().getName()+": entro nel treno "+treno); n_passeggeri[treno]++; stampaStato(); // HO MODIFICATO LO STATO E ORA POSSO RISVEGLIARE IL TRENO SE NECESSARIO if(n_passeggeri[treno] >= MIN) { System.out.println(Thread.currentThread().getName()+": sveglio il treno "+treno); attesaPasseggeri[stazione].Signal(); } System.out.println(Thread.currentThread().getName()+" mi sospendo per il viaggio nel treno "+treno); codaViaggio[treno].Wait(); stampaStato(); n_passeggeri[treno]--; System.out.println(Thread.currentThread().getName()+" scendo, sono arrivato"); // come ultima istruzione bisogna invocare esciMonitor esciMonitor(); } // Utilizzato dal treno public void entraStazione(int stazione, int treno) { // come prima istruzione bisogna invocare entraMonitor entraMonitor(); stampaStato(); if(treno_fermo[stazione]!=-1) // se il binario occupato { System.out.println("\t"+Thread.currentThread().getName()+": non posso entrare in stazione "+((stazione==MonitorStazione.A)?"A":"B")); attesaBinario[stazione].Wait(); } stampaStato(); System.out.println("\t"+Thread.currentThread().getName()+" entro nel binario della stazione "+((stazione==MonitorStazione.A)?"A":"B")); // acquisisco il binario treno_fermo[stazione]=treno; // come ultima istruzione bisogna invocare esciMonitor esciMonitor(); } // Utilizzato dal treno public void scaricaPasseggeri(int stazione, int treno) { // come prima istruzione bisogna invocare entraMonitor entraMonitor(); System.out.println("\t"+Thread.currentThread().getName()+" Scarico i passeggeri arrivati alla stazione "+((stazione==MonitorStazione.A)?"A":"B")); while(codaViaggio[treno].queue()) codaViaggio[treno].Signal(); stampaStato(); // come ultima istruzione bisogna invocare esciMonitor esciMonitor(); } //Utilizzato dal treno public void caricaPasseggeri(int stazione, int treno) { // come prima istruzione bisogna invocare entraMonitor entraMonitor(); System.out.println("\t"+Thread.currentThread().getName()+" Sveglio i passeggeri in attesa sul binario della stazione "+((stazione==MonitorStazione.A)?"A":"B")); stampaStato(); // risveglio i passeggeri in attesa per lasciare entrare quelli che devono prendere questo treno int sospesi = contPasseggeri[stazione]; //utilizzo questa variabile per risvegliare TUTTI i processi perch altrimenti // contPasseggeri[stazione] viene decrementato ogni volta che viene fatta la Signal for(int i=0; i0; i--) attesaTreno[stazione].Signal(); } // inizio il viaggio System.out.println("\t"+Thread.currentThread().getName()+" inizio il viaggio dalla stazione "+((stazione==MonitorStazione.A)?"A":"B")); // libero il binario e risveglio un altro treno in attesa di quel binario treno_fermo[stazione]=-1; attesaBinario[stazione].Signal(); stampaStato(); // come ultima istruzione bisogna invocare esciMonitor esciMonitor(); } public void svegliaTreno(int stazione) { // come prima istruzione bisogna invocare entraMonitor entraMonitor(); System.out.println(Thread.currentThread().getName()+": Risveglio il treno fermo alla stazione "+((stazione==MonitorStazione.A)?"A":"B")); attesaPasseggeri[stazione].Signal(); // come ultima istruzione bisogna invocare esciMonitor esciMonitor(); } }