Oggi si nuota! La verifica consiste nell’implementare un monitor per la sincronizzare dei thread che rappresentano i nuotatori di diverse squadre e lo starter della gara. La competizione si svolge su una piscina suddivisa in corsie, ciascuna delle quali è occupata ad una squadra. Lo starter dà il via quando il primo nuotatore di ogni squadra è schierato sulla griglia di partenza. Ogni nuotatore deve fare due vasche prima di lasciare il posto al nuotatore successivo della propria squadra.
Dovete implementare i seguenti metodi della classe Piscina.java
contenuta nel file ZIP:
- void chiediMutex(int x, int y): chiede il mutex per accedere alla posizione (x, y). Viene invocato dai nuotatori prima di eseguire lo spostamento.
- void rilasciaMutex(int x, int y): rilascia il mutex in posizione (x, y). Viene invocato dai nuotatori quando abbandonano la posizione (x, y).
- void attendiPartenza(int corsia): il nuotatore è schierato in bordo vasca e deve attendere il momento in cui può partire.
- void arrivato(int corsia): il nuotatore ha terminato le due vasche, il successivo può partire.
- void attendiSchieramento(): viene invocato dallo starter per attendere che tutti i (primi) nuotatori siano schierati.
- void daiVia(): a schieramento completato, lo starter dà inizio alla gara.
Un nuotatore esegue le seguenti operazioni:
- raggiunge il bordo vasca (usando chiediMutex e rilasciaMutex);
- attende di potersi tuffare (invocando attendiPartenza);
- si tuffa e fa le 2 vasche (usando chiediMutex e rilasciaMutex);
- notifica che è arrivato (tramite la funzione arrivato);
- esce dalla vasca e si posiziona all’esterno (usando chiediMutex e rilasciaMutex).
Lo starter attende che i nuotatori si siano schierati (usando attendiSchieramento) e dà il via alla gara (usando daiVia).
Si poteva risolvere il via dello starter con un contatore “partenza” inizializzato a zero, in questo modo:
public synchronized void attendiPartenza(int corsia) throws InterruptedException {
partenza++;
notifyAll();
while(!attesa[corsia]){
wait();
}
attesa[corsia]=false;
}
public synchronized void attendiSchieramento() throws InterruptedException {
while(partenza<corsie){
wait();
}
}
public synchronized void daiVia() {
for(int i=0;i<corsie;i++){
partenza[i]=true;
}
notifyAll();
}
}