Personalmente ritengo la soluzione AtomicInteger
è un po' brutto, perché introduce una gara condizionata che significa che il tentativo di aggiornamento potrebbe "fallire" e hanno da ripetere (eseguendo un'iterazione all'interno del ciclo while) rendendo il tempo di aggiornamento meno deterministico rispetto all'effettuazione dell'intera operazione in una sezione critica.
Scrivere il proprio contatore è così banale che consiglierei questo approccio. È anche più bello da una prospettiva OO in quanto espone solo le operazioni che ti è consentito eseguire.
public class Counter {
private final int max;
private int count;
public Counter(int max) {
if (max < 1) { throw new IllegalArgumentException(); }
this.max = max;
}
public synchronized int getCount() {
return count;
}
public synchronized int increment() {
count = (count + 1) % max;
return count;
}
}
EDIT
L'altro problema percepisco con la soluzione ciclo while è che, dato un gran numero di thread che tentano di aggiornare il contatore si potrebbe finire con una situazione in cui si dispone di diverse discussioni dal vivo girando e tentando di aggiornare il contatore. Dato che solo 1 thread avrebbe avuto successo, tutti gli altri thread avrebbero fallito causandone l'iterazione e sprecando i cicli della CPU.
Mi chiedo se questo sarebbe veramente atomica se filo perde la priorità tra '' 'this.ai.get()' '' e '' '} while (! This.ai.compareAndSet (CURVAL, newal)) '' ' –
@ Renato Indietro: Sì, lo farebbe. CAS semantic lo garantisce. –