Soluzione
Esercizio 007 - Metodi synchronized
Nell'esempio:
class
Sample {
int a;
synchronized void one(){
a=1;
System.out.println("a=" + a);
}
void two(){
a=2;
}
}
c'è
un unico uso di synchronized
ed è quello citato nel metodo one!
Poiché nessun altro usa synchronized
(neppure nei due threads che chiamano ripetutamente i metodi one
e two)
si ha che tutte le chiamate di one
avranno immediato successo perché non troveranno mai la risorsa
Sample
locked. Di conseguenza i metodi one
e two
non sono sincronizzati in nessun modo tra di loro e quindi l'applicazione
stampa infinite stringhe "a=1" e "a=2" casualmente mischiate tra di loro.
Morale
di questa favola: il meccanismo di lock di Java offerto dalla primitiva
synchronized
è cooperativo e quindi tutti coloro che lo utilizzano devono prima
accordarsi sulle loro modalità di utilizzo. Non è sufficiente
aggiungere un solo synchronized
ad un metodo per assicurarsi un accesso sincrono e locked ad un insieme
di risorse.
Notiamo
infine che:
-
Togliere
synchronized
non cambia il risultato dell'esercizio.
-
Aggiungere
un volatile
alla dichiarazione di a
non cambia il risultato dell'esercizio.
-
Aggiungere
un synchronized
alla dichiarazione di two
cambia finalmente il risultato ottenuto: l'applicazione stamperà
infinite stringhe "a=1".
|