0Pricing
Java Academy · Lektion

Atomare Variablen: Aktualisierungen ohne Locks

Verwenden Sie AtomicInteger, AtomicLong und AtomicReference für threadsichere Zähler ohne Locks.

Atomare Variablen: Aktualisierungen ohne Locks ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Das Problem mit nichtatomaren Operationen

Das einfache Inkrement count++ ist NICHT threadsicher — es besteht aus drei Operationen: Lesen, Addieren, Schreiben. Gleichzeitig ausgeführte Threads können diese Operationen verschachteln, wodurch Aktualisierungen verloren gehen. Atomare Variablen lösen dieses Problem ohne Sperren.

// UNSAFE:
int count = 0;
// Thread A reads count=0, Thread B reads count=0
// Both write 1 — second update lost!
count++; // NOT thread-safe

// SAFE:
import java.util.concurrent.atomic.*;
AtomicInteger atomicCount = new AtomicInteger(0);
atomicCount.incrementAndGet(); // atomic, lock-free

Grundlagen von AtomicInteger

AtomicInteger stellt Integer-Operationen bereit, die mithilfe von Compare-and-Swap-Anweisungen (CAS) der CPU garantiert atomar sind — Sperren werden nicht benötigt.

AtomicInteger counter = new AtomicInteger(0);

counter.set(10);                   // set to 10
System.out.println(counter.get()); // 10

int prev = counter.getAndIncrement(); // returns 10, sets to 11
int curr = counter.incrementAndGet(); // sets to 12, returns 12
counter.addAndGet(5);                 // adds 5, returns 17
counter.decrementAndGet();            // subtracts 1, returns 16

compareAndSet: Die CAS-Operation

compareAndSet(expected, update) aktualisiert den Wert nur dann atomar, wenn er aktuell dem erwarteten Wert entspricht. Die Methode gibt true zurück, wenn die Aktualisierung erfolgreich war. Dies bildet die Grundlage aller sperrenfreien Algorithmen.

AtomicInteger ai = new AtomicInteger(5);

boolean updated = ai.compareAndSet(5, 10); // current==5? set to 10
System.out.println(updated); // true
System.out.println(ai.get()); // 10

boolean failed = ai.compareAndSet(5, 20); // current==10, not 5 → fails
System.out.println(failed); // false
System.out.println(ai.get()); // still 10

AtomicLong für Zähler

AtomicLong ist das entsprechende 64-Bit-Pendant. Es wird häufig für Sequenzgeneratoren und Trefferzähler verwendet:

AtomicLong seq = new AtomicLong(0);

// Thread-safe sequence generator:
long nextId() {
    return seq.incrementAndGet();
}

System.out.println(nextId()); // 1
System.out.println(nextId()); // 2
System.out.println(nextId()); // 3

AtomicBoolean

Threadsicheres boolesches Flag. Wird häufig für eine einmalige Initialisierung oder Signale zum Herunterfahren verwendet:

AtomicBoolean initialized = new AtomicBoolean(false);

void initOnce() {
    // compareAndSet: only first caller succeeds
    if (initialized.compareAndSet(false, true)) {
        System.out.println("Initializing...");
        // perform expensive init
    } else {
        System.out.println("Already initialized");
    }
}

AtomicReference

AtomicReference<V> stellt atomare Aktualisierungen einer Objektreferenz bereit. Es wird zur Implementierung sperrenfreier Datenstrukturen verwendet:

import java.util.concurrent.atomic.*;

record Config(String host, int port) {}

AtomicReference<Config> configRef =
    new AtomicReference<>(new Config("localhost", 8080));

// Hot-swap the configuration atomically:
Config oldConfig = configRef.get();
Config newConfig = new Config("prod.example.com", 443);

boolean swapped = configRef.compareAndSet(oldConfig, newConfig);
System.out.println(swapped); // true
System.out.println(configRef.get()); // Config[host=prod.example.com, port=443]

updateAndGet / getAndUpdate

Wenden Sie mithilfe einer intern verwendeten CAS-Wiederholungsschleife eine Funktion atomar an:

AtomicInteger value = new AtomicInteger(10);

// Apply function atomically: square the value
int newVal = value.updateAndGet(x -> x * x);
System.out.println(newVal); // 100

// Get old, then apply:
int old = value.getAndUpdate(x -> x + 1);
System.out.println(old);   // 100
System.out.println(value.get()); // 101

accumulateAndGet

Kombinieren Sie den aktuellen Wert mithilfe einer Funktion mit einem angegebenen Wert:

AtomicInteger max = new AtomicInteger(0);

// Keep running maximum:
max.accumulateAndGet(42, Math::max); // max(0, 42) = 42
max.accumulateAndGet(15, Math::max); // max(42, 15) = 42
max.accumulateAndGet(99, Math::max); // max(42, 99) = 99

System.out.println(max.get()); // 99

LongAdder für Zähler mit hoher Konkurrenz

Bei hoher Konkurrenz zwischen Threads können die CAS-Wiederholungen von AtomicLong die Leistung beeinträchtigen. LongAdder verwendet mehrere Zellen, um die Konkurrenz zu verringern:

import java.util.concurrent.atomic.*;

LongAdder adder = new LongAdder();

// Multiple threads can call add() with minimal contention:
adder.increment();
adder.add(5);
adder.increment();

System.out.println(adder.sum()); // 7
// Note: sum() is NOT atomic with add() — use only when no concurrent adds

Atomare Arrays

AtomicIntegerArray / AtomicLongArray stellen atomare Operationen für einzelne Array-Elemente bereit:

AtomicIntegerArray arr = new AtomicIntegerArray(5);

arr.set(0, 10);
arr.incrementAndGet(0);
arr.compareAndSet(2, 0, 42); // index 2: if 0, set 42

System.out.println(arr.get(0)); // 11
System.out.println(arr.get(2)); // 42

Wann Sie Atomics statt Sperren verwenden sollten

Verwenden Sie atomare Variablen, wenn:

  • Variablen einzeln aktualisiert werden (Zähler, Flags, Referenzen)
  • nur geringe Konkurrenz vorliegt
  • sperrenfreie Leistung wichtig ist

Verwenden Sie Sperren, wenn:

  • mehrere Variablen atomar aktualisiert werden müssen
  • komplexe bedingte Logik erforderlich ist
  • sehr hohe Konkurrenz vorliegt (CAS-Wiederholungen beeinträchtigen die Leistung)

Kurzer Test

Was garantiert compareAndSet(expected, update)?

Zusammenfassung: Atomare Variablen

Wichtige Erkenntnisse:

  • Atomare Typen verwenden CAS-Anweisungen der CPU — sie sind sperrenfrei und threadsicher
  • AtomicInteger/Long/Boolean/Reference für Atomizität einzelner Variablen
  • compareAndSet bildet die Grundlage sperrenfreier Algorithmen
  • updateAndGet/accumulateAndGet für funktionale Aktualisierungen
  • LongAdder für Zähler-Szenarien mit hoher Konkurrenz

Häufig gestellte Fragen

Ist die Lektion „Atomare Variablen: Aktualisierungen ohne Locks“ kostenlos?

Ja — der vollständige Text von „Atomare Variablen: Aktualisierungen ohne Locks“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Atomare Variablen: Aktualisierungen ohne Locks“?

Verwenden Sie AtomicInteger, AtomicLong und AtomicReference für threadsichere Zähler ohne Locks. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Atomare Variablen: Aktualisierungen ohne Locks“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. ReentrantLock vs. synchronized
  2. ReadWriteLock für Leser-Schreiber-Szenarien
  3. Atomare Variablen: Aktualisierungen ohne Locks
  4. StampedLock und optimistische Lesezugriffe
← Zurück zu Java Academy