W Javie praca z wątkami realizowana jest za pomocą klas Thread, Runnable oraz z pakietu java.util.concurrent. Aby zorganizować bezpieczeństwo wątków, stosuje się różne mechanizmy synchronizacji:
synchronized) pozwalają wielu wątkom na dostęp do wspólnych danych bez wyścigów.ReentrantLock, Semaphore, AtomicInteger, ConcurrentHashMap) zapewniają bardziej elastyczne sposoby synchronizacji.Przykład synchronizacji:
public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }
Przykład z użyciem klas atomowych:
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(); } }
Czy kluczowe słowo volatile gwarantuje bezpieczeństwo wątków przy inkrementacji licznika typu int?
Odpowiedź: Nie. volatile zapewnia tylko widoczność wartości między wątkami, ale nie atomowość operacji. Inkrementacja nie jest operacją atomową (count++ składa się z odczytu, zwiększenia i zapisu), dlatego możliwe są straty danych. Dla bezpiecznej inkrementacji wątkowej potrzebna jest synchronizacja lub klasy takie jak AtomicInteger.
volatile int count = 0; // count++ nie jest bezpieczne dla wątków!
Historia
W sklepie internetowym bonusowy rachunek był aktualizowany przez licznik volatile. Pod dużym obciążeniem tysiące użytkowników zamawiały towary, a część bonusów znikała z powodu wyścigu wątków przy count++.
Historia
Pracownik używał zwykłej ArrayList jako wspólnego bufora między producentem a konsumentem w aplikacji wielowątkowej, w wyniku czego pojawiały się ConcurrentModificationException. Rozwiązaniem było zastosowanie bloków synchronized lub zamiana na CopyOnWriteArrayList.
Historia
W przetwarzaniu płatności, programista wykonywał operację "sprawdź i pobierz kwotę" przez dwie niezwiązane metody. W warunkach dużego obciążenia prowadziło to do podwójnego obciążenia, dopóki nie wprowadzono atomowych transakcji i blokad.