Esercizio 1.4: Risoluzione dei colli di bottiglia del thread
Prima di iniziare, è necessario aver completato l'Esercizio 1.3:
Individuazione dei colli di bottiglia del thread.
Per individuare la condizione di stallo nel codice, è possibile utilizzare il Diagramma sequenza UML2 (viste Interazioni oggetto e Interazioni thread) e la risorsa di creazione profili Stack di chiamata in Controllo creazione profili, in aggiunta alla vista Thread.
Per risolvere questa condizione di stallo, per prima cosa individuare le chiamate di metodo e gli oggetti coinvolti nel problema:
- Nella vista Thread, individuare il primo thread philo* con lo stato "In attesa del blocco". Posizionare il cursore sul segmento "In attesa del blocco". La descrizione comandi identifica il blocco di cui il thread è in attesa: Fork.<numero id>.
- Fare clic con il pulsante destro del mouse sulla risorsa di creazione profili per l'esecuzione e selezionare Apri con > Interazioni oggetto UML2. Viene visualizzata la vista Diagramma sequenza UML2 che contiene le interazioni oggetto.
- Nel diagramma della sequenza, scorrere la vista per individuare Fork.<numero id> e fare doppio clic per selezionarlo.
- Scorrere verso il basso per individuare una freccia orizzontale che parte da uno dei thread philo* fino a Fork.<numero id>. Queste frecce mostrano le interazioni tra gli oggetti e la prima interazione tra questi due oggetti indica che il thread philo* ha acquisito Fork.<numero id>. Viene individuata una freccia con l'etichetta getName.
- Fare doppio clic su getName. Nella vista Thread, l'indicatore verticale Ora corrente si sposta per visualizzare cosa è accaduto nell'intero programma quando è stato richiamato getName. È possibile vedere che la richiesta ha avuto esito positivo se lo stato del thread philo* che sta effettuando la richiesta non è "In attesa del blocco".
- Nel diagramma della sequenza, fare di nuovo doppio clic su Fork.<numero id> e scorrere verso il basso per individuare una richiesta getName originata in un altro thread philo*.
- Fare doppio clic su questa istanza di getName. L'indicatore Ora corrente mostrerà che il thread philo* che effettua la richiesta non ottiene il Fork.<numero id> ed entra nello stato "In attesa del blocco".
In questa istanza, il problema è costituito da una richiesta di Fork bloccata da un altro thread. Controllare gli altri thread con lo stato "In attesa del blocco" per verificare che sia vero anche in altre istanze.
A questo punto, individuare il metodo che causa il problema:
- Fare clic con il pulsante destro del mouse sulla risorsa di creazione profili per l'esecuzione e selezionare Apri con > Interazioni thread UML2. Viene visualizzata la vista Diagramma sequenza UML2 nella quale appaiono le interazioni del thread.
- In Controllo creazione profili, espandere la risorsa di creazione profili, quindi la voce Analisi thread e Stack di chiamata.
- Nella vista Thread, nel punto in cui vengono visualizzati i nomi dei thread, fare doppio clic sul primo thread philo* con lo stato "In attesa del blocco". Notare che la vista Interazioni thread cambia per visualizzare le informazioni relative solo a tale thread.
- Scorrere verso il basso fino alla fine delle informazioni sul thread e fare doppio clic sull'ultimo metodo di esecuzione del thread: il metodo di esecuzione. Lo Stack di chiamata in Controllo creazione profili visualizza tutte le chiamate sullo stack in quel momento.
- Nello Stack di chiamata, notare che il thread che detiene il blocco ha chiamato il metodo Sospensione in Philosopher.java; oppure che è ancora in attesa di un blocco e quindi è sospeso.
- Controllare gli altri thread che terminano l'esecuzione in attesa di un blocco; il metodo Sospensione in Philosopher.java spesso si trova in Stack di chiamata e potrebbe costituire il problema.
Controllare il metodo Sospensione. Verificare il codice:
- Nello Stack di chiamata, fare clic con il pulsante destro del mouse su un'istanza di Sleep(int) void [Philosopher.java] e selezionare Apri origine. L'origine viene visualizzata nell'editor in corrispondenza della classe Sospensione.
- Esaminare il codice. Tenere presente che il metodo Sospensione viene richiamato dall'interno del metodo di esecuzione. Prima, è presente una chiamata alla traccia mediante la quaale viene stampato il messaggio"got left..."e quindi una chiamata a Sospensione. Inserendo un commento alla chiamata a Sospensione potrebbe essere possibile evitare la condizione di stallo.
- Inserire un commento per Sospensione.
- Selezionare File > Salva.
A questo punto, creare nuovamente il profilo del programma.
Questa volta il programma viene eseguito senza che si verifiche una condizione di stallo e sulla console viene visualizzato il seguente messaggio:
HeadWaiter reports all philosophers have finished dining normally
Nella vista Thread e nelle altre viste viene visualizzato cosa accade ai thread durante l' esecuzione del programma. L'utente deve eseguire l'analisi e risolvere la condizione di stallo in base alla conoscenza del programma.
Terminare questa esercitazione revisionando il materiale nel Riepilogo.