Comments
Transcript
Esercitazione 15 Il problema dello Sleeping Barber
Università degli Studi della Calabria Corso di Laurea in Ingegneria Informatica A.A. 2001/2002 Sistemi Operativi Corsi A e B Esercitazione 15 Il problema dello Sleeping Barber E’ dato un salone di barbiere, avente un certo numero di posti d’attesa ed un’unica poltrona di lavoro. Nel salone lavora un solo barbiere, il quale è solito addormentarsi sulla poltrona di lavoro in assenza di clienti. Un cliente che arrivi al salone può trovare le seguenti situazioni: • Il barbiere dorme sulla poltrona di lavoro. Il cliente sveglia il barbiere e si accomoda sulla poltrona di lavoro, quindi il barbiere lo serve. • Il barbiere sta servendo un altro cliente: se ci sono posti d’attesa liberi, il cliente attende, altrimenti se ne va. Scrivere in Java un programma che risolva tale problema, simulando l’attività dei diversi soggetti (il Salone, il Barbiere, i Clienti) ed evidenziandone su video lo stato. L’implementazione della soluzione deve far uso delle opportune primitive di sincronizzazione e mutua esclusione. 1 Il problema dello Sleeping Barber public class SleepingBarber { public static void main (String args[]) { int postiDiAttesa=5; Salone s = new Salone (postiDiAttesa); Barbiere b = new Barbiere (s); b.start(); for (int i = 1; i < 10; i++) { Cliente c = new Cliente (s, i); c.start (); } } } class Salone { … } class Barbiere extends Thread { … } class Cliente extends Thread { … } Barbiere class Barbiere extends Thread { private Salone salone; public Barbiere (Salone salone) { this.salone = salone; } public void run () { while (true) salone.servizio(); } } 2 Cliente (1) class Cliente extends Thread { private Salone salone; private int id; public Cliente (Salone salone, int id) { this.salone = salone; this.id = id; } public void run () { while (true) { int tempoDiRicrescita = 1000+(int)(Math. random()*3000); System.out.println ("Il cliente "+id+" attende la (ri)crescita dei capelli. "+ "Tempo di (ri)crescita = "+tempoDiRicrescita); try { Thread.sleep (tempoDiRicrescita); } catch (InterruptedException e) { System.out.println (e); } int tempoDiServizio = salone. entraSalone(id); … Cliente (2) … if (tempoDiServizio != -1) { try { Thread.sleep (tempoDiServizio); } catch (InterruptedException e) { System.out.println (e); } System.out.println ("Il cliente "+id+" e' stato servito e lascia il salone"); } salone.lasciaSalone(tempoDiServizio); } } } 3 Salone (1) class Salone { private int postiDiAttesa; private int postiDiAttesaOccupati; private int clientiPresenti; private boolean barbiereDorme; private boolean poltronaDiLavoroOccupataDaCliente; public Salone (int posti) { postiDiAttesa = posti; postiDiAttesaOccupati = 0; clientiPresenti = 0; barbiereDorme = true; poltronaDiLavoroOccupataDaCliente = false; } public synchronized void lasciaSalone (int esitoIngresso) { … } public synchronized int entraSalone (int idCliente) { … } public synchronized void servizio () { … } Salone: entraSalone (1) public synchronized int entraSalone (int idCliente) { if (postiDiAttesaOccupati == postiDiAttesa) { System.out.println ("Il cliente "+idCliente+" entra nel salone, non trova " + "posto e lascia il salone"); return -1; } else if (!barbiereDorme) { clientiPresenti++; System.out.println ("Il cliente "+idCliente+" entra nel salone e si mette in "+ "attesa"); postiDiAttesaOccupati++; System.out.println ("Posti di attesa occupati = "+postiDiAttesaOccupati); do { try { wait(); } catch (InterruptedException e) { System.out.println (e); } } while (poltronaDiLavoroOccupataDaCliente); … 4 Salone: entraSalone (2) … barbiereDorme = false; System.out.println ("Posti di attesa occupati = "+postiDiAttesaOccupati); int tempoDiServizio = 1000+(int)(Math. random()*4000); System.out.println ("Il cliente "+idCliente+" inizia ad essere servito. "+ "Tempo di servizio = "+tempoDiServizio+" ms"); poltronaDiLavoroOccupataDaCliente = true; postiDiAttesaOccupati--; return tempoDiServizio; } else // il barbiere dorme { clientiPresenti++; System.out.println ("Il cliente "+idCliente+" entra nel salone e sveglia il "+ "barbiere"); barbiereDorme = false; notifyAll(); // per svegliare il barbiere int tempoDiServizio = 1000+(int)(Math.random()*4000); … Salone: entraSalone (3) … System.out.println ("Il cliente "+idCliente+" inizia ad essere servito. "+ "Tempo di servizio = "+tempoDiServizio+" ms"); poltronaDiLavoroOccupataDaCliente = true; return tempoDiServizio; } } 5 Salone: lasciaSalone public synchronized void lasciaSalone (int esitoIngresso) { if (esitoIngresso != -1) { clientiPresenti--; poltronaDiLavoroOccupataDaCliente = false; System.out.println ("Posti di attesa occupati = "+ postiDiAttesaOccupati); if (postiDiAttesaOccupati > 0) { System.out.println ("Si svegliano i clienti in attesa"); notifyAll(); } } } Salone: servizio public synchronized void servizio () { if (clientiPresenti == 0) { System.out.println ("Il barbiere approfitta dell'assenza "+ "di clienti per dormire"); barbiereDorme = true ; try { wait(); } catch (InterruptedException e) {System.out.println (e);} barbiereDorme = false; notifyAll(); } } 6