Altri hanno indirizzato al "perché?". E 'facile comunque a rotolare il proprio Add(ref double, double)
, utilizzando il CompareExchange
primitiva:
public static double Add(ref double location1, double value)
{
double newCurrentValue = location1; // non-volatile read, so may be stale
while (true)
{
double currentValue = newCurrentValue;
double newValue = currentValue + value;
newCurrentValue = Interlocked.CompareExchange(ref location1, newValue, currentValue);
if (newCurrentValue == currentValue)
return newValue;
}
}
CompareExchange
imposta il valore di location1
essere newValue
, se il valore corrente è uguale a currentValue
. Così facendo in modo atomico e sicuro per i thread, possiamo fare affidamento solo su di esso senza ricorrere alle serrature.
Perché il ciclo while (true)
? I cicli come questo sono standard quando si implementano algoritmi concorrentemente ottimistici. CompareExchange
non cambierà location1
se il valore corrente è diverso da currentValue
. Ho inizializzato currentValue
su location1
- facendo una lettura non volatile (che potrebbe essere stantia, ma che non cambia la correttezza, come CompareExchange
controllerà il valore). Se il valore corrente (ancora) è quello che abbiamo letto da location
, CompareExchange
cambierà il valore in newValue
. In caso contrario, è necessario riprovare CompareExchange
con il nuovo valore corrente, come restituito da CompareExchange
.
Se il valore viene modificato da un altro thread fino al momento del nostro prossimo CompareExchange
, fallirà di nuovo, rendendo necessario un altro tentativo, e questo in teoria può andare avanti per sempre, da qui il ciclo. A meno che non si modifichi costantemente il valore da più thread, è probabile che il numero CompareExchange
venga chiamato una sola volta, se il valore corrente è ancora quello restituito dalla lettura non volatile di location1
o due volte se era diverso.
fonte
2013-06-03 09:27:35
Il link non è più attivo. Ecco un backup da Internet Archive https://web.archive.org/web/20160319061137/http://www.codemaestro.com/reviews/8 –