Wat is het verschil tussen volatile en atomaire variabelen?
sobes.tech AI
Antwoord van AI
volatile zorgt voor de zichtbaarheid van wijzigingen in een variabele voor verschillende threads en verbiedt de compiler en JVM om instructies gerelateerd aan deze variabele te herschikken. Dit garandeert dat bij het lezen van een volatile variabele, de thread de meest recente geschreven waarde ziet. Echter, volatile garandeert niet de atomairheid van samengestelde operaties (bijvoorbeeld incrementeer).
De atomische klassen uit de package java.util.concurrent.atomic (zoals AtomicInteger, AtomicLong, AtomicReference) gebruiken low-level atomische operaties zoals Compare-And-Swap (CAS), die op hardware-niveau worden uitgevoerd. Ze garanderen dat lees-wijzig-schrijf operaties atomair worden uitgevoerd, zonder expliciete synchronisatie met synchronized.
Vergelijking:
| Kenmerk | volatile |
Atomische variabelen (AtomicInteger, etc.) |
|---|---|---|
| Atomairheid | Garant niet de atomairheid van samengestelde operaties. | Garanderen de atomairheid van operaties (CAS). |
| Zichtbaarheid | Garandeert de zichtbaarheid van wijzigingen voor andere threads. | Garandeert de zichtbaarheid (bijwerking van CAS). |
| Gebruik | Voor het garanderen van zichtbaarheid bij eenvoudige lezen/schrijven. | Voor atomische operaties zoals incrementeer, CAS. |
| Overhead | Minder overhead dan synchronized. |
Over het algemeen minder overhead dan synchronized bij lage competitie. |
Voorbeeld van gebruik van volatile:
class SharedData {
volatile boolean flag = false; // Zorgt voor zichtbaarheid van flag
public void setFlag() {
flag = true;
}
public boolean isFlag() {
return flag;
}
}
Voorbeeld van gebruik van AtomicInteger:
import java.util.concurrent.atomic.AtomicInteger;
class Counter {
AtomicInteger count = new AtomicInteger(0); // Atomische teller
public void increment() {
count.incrementAndGet(); // Atomische incrementeer
}
public int getCount() {
return count.get();
}
}