In Java wordt het werken met threads geïmplementeerd via de klassen Thread, Runnable en uit het pakket java.util.concurrent. Voor het organiseren van threadveiligheid worden verschillende synchronisatiemechanismen gebruikt:
synchronized) stellen meerdere threads in staat om toegang te krijgen tot gedeelde gegevens zonder racecondities.ReentrantLock, Semaphore, AtomicInteger, ConcurrentHashMap) bieden flexibeler manieren van synchronisatie.Voorbeeld van synchronisatie:
public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }
Voorbeeld met gebruik van atomische 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(); } }
Garandeert het sleutelwoord volatile threadveiligheid bij het verhogen van een int-teller?
Antwoord: Nee. volatile biedt alleen zichtbaarheid van de waarde tussen threads, maar niet de atomiciteit van bewerkingen. Verhogen is geen atomische bewerking (count++ bestaat uit lezen, verhogen en schrijven), daarom kunnen gegevens verloren gaan. Voor threadveilige verhogingen zijn synchronisatie of klassen zoals AtomicInteger nodig.
volatile int count = 0; // count++ is niet threadveilig!
Verhaal
In een online winkel werd de bonusrekening bijgewerkt via een volatile-teller. Onder belasting bestelden duizenden gebruikers producten, en een deel van de bonussen ging verloren vanwege racecondities op count++.
Verhaal
Een medewerker gebruikte een gewone ArrayList als een gedeelde buffer tussen een producent en een consument in een multithread-applicatie, wat resulteerde in ConcurrentModificationException. De oplossing was het gebruik van synchronized-blokken of vervanging door CopyOnWriteArrayList.
Verhaal
Bij de verwerking van betalingen voerde een ontwikkelaar de operatie "controleer en neem het bedrag af" uit via twee niet-verbonden methoden. Onder hoge belasting leidde dit tot dubbele afschrijvingen, totdat atomische transacties en vergrendelingen werden geïmplementeerd.