Buongiorno a tutti, chiedo aiuto su un esercizio complicato per quanto riguarda la sincronizzazione.
Spiego meglio il mio problema descrivendolo.
Un sueprmercato dispone di 3 addetti e 3 casse. Per oni cassa non sono ammesse file con più di 5 clienti. Accade spesso che un addetto debba allontanarsi dalla cassa per assistere un cliente durante la spesa ed in tal caso i clienti già in fila vengano accodati in modo ordinato nelle altre casse, dando priorità alle casse più vicine, purchè le nuove file non superino la massima lunghezza consentita.
I clienti aspetteranno, e successivamente si accoderanno in modo casuale, qualora tutte le file siano già composte da 5 clienti.
Io ho pensato di usare la politica del produttore consumatore, quindi, ho creato una classe cliente(thread), addetto(thread), supermercato(risorsa condivisa) e una classe cassa dove sono presenti solo 2 variabili una int coda e una boolean stato cassa chiusa/aperta per creare un array ad oggetti nella classe supermercato.
Posto il codice supermercato, essendo che nel cliente abbiamo un metodo paga() e nell'addetto un metodo incassa(), quindi il cliente incrementa una variabile e l'addetto decrementa tale variabile.
codice classe supermercato:
l'output che viene fuori da questo primo codice è il seguente:codice://Classe Supermercato condivisa tra tutti i thread clienti e addetti public class Supermercato { static int MAX_CASSE;//indica il numero massimo di casse disponibili private int MAX_CODA;//indica la coda massima di ongni singola coda private Cassa casse[]; //creo un array di tipo Cassa //----------------------------------------------------COSTRUTTORE---------------------------------- public Supermercato(){ MAX_CASSE=3;//inizializzazione max_casse MAX_CODA=5;//inizializzaziond max_coda casse = new Cassa[MAX_CASSE];//inizializzo l'array formato da 3 celle //inizializzazione casse tramite costruttore for(int i=0; i<casse.length; i++){ casse[i] = new Cassa(0, true, "Cassa"+i);//inizializzo a zero la coda poi a true(aperta) la cassa e gli passo un nome }//fine for }//fine costruttore //------------------------------------------------------METODI--------------------------------------- //questo metodo permette la scelta della cassa migliore, quindi con minor numero di clienti in coda----------------------------- public String scegliCassa() { if( casse[0].get_coda() <= casse[1].get_coda() ){ if( casse[0].get_coda() <= casse[2].get_coda() ){ return casse[0].get_nome(); }else return casse[2].get_nome(); }else if(casse[1].get_coda() <= casse[2].get_coda() ){ return casse[1].get_nome(); }else return casse[2].get_nome(); }//fine metodo scegliCassa //questo metodo aggiunge un cliente alla coda, incrementando l'opportuna variabile-------------------------------------- public synchronized void paga(){ System.out.println("Il " + Thread.currentThread().getName() + " è entrato nel supermercato."); System.out.printf("la funzone sceltaCassa ha scelto la %s\n", scegliCassa()); String cassaScelta = scegliCassa(); for(int i=0; i<casse.length; i++){ System.out.printf("entro nel ciclo: %d\n",i); //se il nome della cassa(i) è uguale al nome ritornato dal metodo scegliCassa, la coda è minore di 5, // e lo stato della cassa è true(aperta) il thread si mette in coda nella cassa con minor numero di clienti(thread) if( casse[i].get_nome().equals(cassaScelta) && (casse[i].get_coda()<MAX_CODA) && (casse[i].get_statoCassa()==true) ){ System.out.println("Il " + Thread.currentThread().getName() + " si mette in coda nella " + casse[i].get_nome()); notify();//mando un signal di risveglio casse[i].set_coda("i");//incrementa la coda System.out.printf("Adesso la coda è di %d\n", casse[i].get_coda()); break; }else{//altrimenti essendo che le code delle casse sono tutte piene try { wait();//il cliente si fa una passeggiata(entra in waiting) aspettando che si liberi una delle code. } catch (InterruptedException e) { e.printStackTrace(); }//fine catch }//fine else System.out.printf("ciclo n: %d\n",i); }//fine for }//fine metodo paga public synchronized void incassa(){ }//fine metodo incassa }//fine classe supermercato
Non appena il programma parte, i primi 6 passi sono corretti.codice:Il Cliente9 è entrato nel supermercato. la funzone sceltaCassa ha scelto la Cassa0 entro nel ciclo: 0 Il Cliente9 si mette in coda nella Cassa0 Adesso la coda è di 1 Il Cliente9 ha pagato e sta uscendo. Il Cliente2 è entrato nel supermercato. la funzone sceltaCassa ha scelto la Cassa1 entro nel ciclo: 0 Addetto3 ha passato i prodotti e incassato. Il Cliente7 è entrato nel supermercato. la funzone sceltaCassa ha scelto la Cassa1 entro nel ciclo: 0 Addetto1 ha passato i prodotti e incassato. Il Cliente1 è entrato nel supermercato. la funzone sceltaCassa ha scelto la Cassa1 entro nel ciclo: 0 Il Cliente10 è entrato nel supermercato.
come è possibile che il thread(cliente2) è entrato nella sezione critica neanche il tempo di eseguire il ciclo for entra un altro thread(Cliente7)? non dovrebbe mantenere il look fino a quando non ha finito di eseguire tutte le istruzioni presenti all'interno del metodo paga()?
Poi, la politica che sto utilizzando vi sembra una politica buona? avete piccoli ma grandi consigli?
Cosa sbaglio?![]()
Grazie in anticipo...spero in un vostro aiuto...

Rispondi quotando