2016-08-06 6 views
1

Der folgende Code funktioniert ohne Race-BedingungWarum ist es möglich, atomare Variablen gleichzeitig ohne Racebedingung in Java zu aktualisieren?

AtomicInteger atomicInt = new AtomicInteger(0); 

ExecutorService executor = Executors.newFixedThreadPool(20); 

IntStream.range(0, 1000) 
    .forEach(i -> executor.submit(atomicInt::incrementAndGet)); 

Hier ist die Implementierung von incrementAndGet ist

public final int incrementAndGet() { 
    for (;;) { 
     int current = get(); 
     int next = current + 1; 
     if (compareAndSet(current, next)) 
      return next; 
    } 
} 

Wir sehen current nicht synchronisiert oder verriegelt ist, nachdem ein Thread die current ein anderer Thread aktualisieren könnte bereits erhalten die current.

Aber es scheint wie atomare Klasse Race Condition einige vermeidet.

Kann jemand auf meinen Fehler hinweisen?

+0

'compareAndSet()' verwendet Sperren. In den meisten Implementierungen wird 'compareAndSet()' eine spezielle Anweisung ausführen, die das Sperren in Hardware durchführt (z. B. die CMPXCHG-Anweisung auf x86-Hardware.) Https://en.wikipedia.org/wiki/Compare-and-swap –

Antwort

3

compareAndSet setzt den Wert (und gibt true zurück) wenn und nur wenn der erste Parameter gleich dem aktuellen Wert AtomicInteger ist.

Das heißt, wenn ein anderer Thread den Wert bereits geändert hätte, wäre current nicht gleich dem aktuellen Wert, und die Schleife würde noch einmal ausgeführt werden.

Von der documentation von compareAndSet(int expect, int update):

Atomar den Wert auf den angegebenen aktualisierten Wert setzt, wenn der aktuelle Wert == der Erwartungswert.

Verwandte Themen