cnesan ha scritto:
Pertanto, non bisogna usare synchronized ma la classe Reentrant che è un equivalente di synchronized ma Reentrant consente l'utilizzo delle LockCondition le quali consentono ad un 'iesimo' thread di capire se la risorsa è già usata da un'altro thread e, se si, può fare qualcosa di diverso ogni volta che ha il controllo dallo scheduler fino a quando non si rende disponibile (attesa ciclica await etc).
@cnesan: non consigliare cose più "avanti" se @tagan ha già problemi a comprendere bene l'uso di cose più basilari.
@tagan: usando SOLO synchronized (e nessun altro meccanismo) la gestione corretta dell'atterraggio si PUÒ fare. Ci sono almeno 2 soluzioni che vengono in mente:
Soluzione 1)
Fare tutta la gestione dell'atterraggio all'interno di un singolo metodo synchronized, che acquisisce il lock su un oggetto "condiviso" (può essere proprio l'oggetto Pista e il metodo appena detto può benissimo essere
in Pista).
In questo modo l'atterraggio è "atomico" e c'è mutua-esclusione tra thread, due aerei NON possono atterrare contemporaneamente!
Soluzione 2)
Usare due metodi in Pista atterra() e libera() MA ATTENZIONE atterra() dovrebbe essere così:
public synchronized
boolean atterra() {
Restituisce boolean perché la logica dovrebbe essere (inUso variabile di istanza boolean):
- Se inUso è true, restituisci false (perché appunto già in uso = non può atterrare)
- Se inUso è false, metti inUso=true e restituisci true (=può atterrare)
In questo modo il metodo atterra() essendo synchronized è comunque "atomico" e garantisce che NON ci possono essere due thread-aerei che mettono inUso true contemporaneamente.
Chiaramente chi chiama atterra(), cioè il thread-aereo, riceverà subito un true/false. Se false potrebbe fare uno sleep per poi ripetere dopo il tentativo di atterra(). Insomma, procede con l'atterraggio solo se atterra() dà true.
Per cose un po' migliori e più corrette nel senso del multi-threading, ad esempio fare proprio andare in "sospensione" il thread finché non si libera la pista, è necessario appunto sfruttare altri meccanismi, come la
condition-queue intrinseca degli oggetti (i wait()/notify() degli oggetti) oppure altro di più alto livello.