Nel post precendente abbiamo visto una applicazione multithread con un problema di concorrenza su di una risorsa condivisa. Ora vediamo come fare in modo che la nostra gestione del conto corrente funzioni come atteso.
Dobbiamo regolamentare l'accesso alla risorsa, ovvero vogliamo creare una sorta di coda di processi in esecuzione sul metodo withdrawl(). Per far questo in Java basta marcare il metodo come synchronized. In pratica questo é l'unico cambiamento che ci serve per evitare lo spiacevole comportamento che abbiamo osservato:
private synchronized boolean withdrawl(int amount) {
if(account.getBalance() >= amount) {
// ...
return true;
}
// can't withdraw
System.out.println(Thread.currentThread().getName() + ": out of money");
return false;
}
A livello implementativo quello che Java fa é mettere a disposizione un semaforo su ogni oggetto. Prima di eseguire un metodo synchronized il thread corrente controlla il semaforo. Se un altro thread é in esecuzione nella zona protetta, il thread corrente si mette in attesa del suo turno sul semaforo. Ma, dato che il semaforo é sull'oggetto e non sul metodo, se i metodi sincronizzati di una classe sono più di uno, non é possibile eseguire due di questi metodi contemporaneamente in due diversi thread.
Nessun commento:
Posta un commento