Quando si lavora con programmi multi-threaded ci si potrebbe chiedere se sia meglio sincronizzare i processi mediante una serie di
wait()/notify() oppure invocazioni del metodo
join(). Anzitutto occorre chiarire la semantica dei metodi:
- wait()/notify() sospendono e risvegliano un processo sul monitor associato all'oggetto sul quale viene richiamto il metodo;
- join() sospende il processo corrente fino a quando il Thread sul quale il metodo è stato chiamato non ha terminato la sua esecuzione (ossia è usito da run()).
Dalla semplice descrizione di cui sopra se ne deduce che il metodo
join() è molto utile quando si ha un thread "padre" che deve attendere la fine dell'esecuzione di tutti i suoi figli, come pure se si hanno processi che devono continuare la propria esecuzione solo dopo che altri processi hanno terminato il loro lavoro. Il meccanismo
wait()/notify() risulta invece più flessibile, poiché può sincronizzare processi che non stanno terminando, e quindi che potrebbero riprendere il loro lavoro. Quello che però molto spesso inganna è che il metodo
join() è equivalente ad una buona sincronizzazione con
wait()/notify(), e quindi non esiste nessuna potenziale differenza di performance nell'utilizzo di un metodo o dell'altro. Infatti, spulciando il codice sorgente di
java.lang.Thread si scopre che il metodo
notify() viene implementato con una "semplice"
wait(), e che di conseguenza quando il thread termina provvede a risvegliare i processi sospesi sul suo monitor.
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
Nessun commento:
Posta un commento