In Java wird die Arbeit mit Threads über die Klassen Thread, Runnable und aus dem Paket java.util.concurrent realisiert. Zur Organisation der Thread-Sicherheit werden verschiedene Synchronisationsmechanismen verwendet:
synchronized) ermöglichen es mehreren Threads, auf gemeinsame Daten ohne Wettbewerb zuzugreifen.ReentrantLock, Semaphore, AtomicInteger, ConcurrentHashMap) bieten flexiblere Möglichkeiten zur Synchronisation.Beispiel für Synchronisation:
public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }
Beispiel mit Verwendung von atomaren Klassen:
import java.util.concurrent.atomic.AtomicInteger; public class AtomicCounter { private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); } public int getCount() { return count.get(); } }
Gewährleistet das Schlüsselwort volatile die Thread-Sicherheit beim Inkrementieren eines int-Zählers?
Antwort: Nein. volatile gewährleistet nur die Sichtbarkeit des Wertes zwischen Threads, jedoch nicht die Atomarität der Operationen. Inkrementieren ist keine atomare Operation (count++ besteht aus Lesen, Erhöhen und Schreiben), daher können Daten verloren gehen. Für einen thread-sicheren Inkrement benötigen Sie Synchronisation oder Klassen wie AtomicInteger.
volatile int count = 0; // count++ ist nicht threadsicher!
Geschichte
In einem Online-Shop wurde der Bonuszähler über einen volatile-Zähler aktualisiert. Unter der Last von Tausenden von Benutzern, die Produkte bestellten, gingen einige Boni aufgrund von Thread-Race-Bedingungen bei count++ verloren.
Geschichte
Ein Mitarbeiter verwendete eine normale ArrayList als gemeinsamen Puffer zwischen Producer und Consumer in einer Multithreading-Anwendung, was zu ConcurrentModificationException führte. Die Lösung bestand darin, synchronisierte Blöcke zu verwenden oder auf CopyOnWriteArrayList umzusteigen.
Geschichte
Bei der Zahlungsabwicklung führte der Entwickler die Operation "überprüfen und abheben" über zwei nicht verbundene Methoden durch. Unter hoher Last führte dies zu doppelten Abbuchungen, bis atomare Transaktionen und Sperren implementiert wurden.