Synchronized: Was es ist, Funktionsprinzip und Verwendung in Java

Autor: IT Sectr Veröffentlicht: 2026-03-19 Lesezeit: 8 Min.

Synchronized ist ein integrierter Synchronisationsmechanismus in der Sprache Java, der exklusiven Zugriff auf kritische Codeabschnitte bietet. Laut Oracle, 2024 garantiert der synchronized-Modifikator, dass nur ein Thread die markierte Methode oder den markierten Block zu einem bestimmten Zeitpunkt ausführen kann. Dieser Mechanismus basiert auf Monitoren — einem grundlegenden Konzept von Betriebssystemen, das die korrekte Funktionsweise von Multithread-Anwendungen aller Komplexitätsstufen gewährleistet.

Wichtige Punkte

  • Synchronized — Java-Schlüsselwort für threadsicheren Datenzugriff.
  • Objektmonitor — der interne Mechanismus, auf dem die Synchronisation basiert.
  • Synchronized-Methode sperrt die gesamte Methode auf Instanz- oder Klassenebene.
  • Synchronized-Block ermöglicht die Synchronisation nur eines Teils des Codes.
  • Deadlock — eines der Hauptprobleme bei verschachtelter Synchronisation.

Was ist synchronized?

Synchronized ist ein Schlüsselwort in Java, das garantiert, dass nur ein Thread zu jeder Zeit einen geschützten Codeabschnitt ausführt und so Datenkorruption bei gleichzeitigem Zugriff verhindert. Es erschien in der ersten Version von Java und bleibt der einfachste Weg, um Threadsicherheit für Entwickler aller Erfahrungsstufen zu gewährleisten.

Definition und Rolle in Java

Der synchronized-Modifikator löst zwei Aufgaben: gegenseitigen Ausschluss (mutual exclusion) und Sichtbarkeit von Änderungen. Wenn ein Thread einen synchronized-Block verlässt, sind alle Änderungen für andere Threads sichtbar, die einen auf demselben Objekt synchronisierten Block betreten.

Synchronized kann auf eine gesamte Methode oder auf einen beliebigen Codeblock unter Angabe eines Monitor-Objekts angewendet werden. In beiden Fällen fügt die JVM auf Bytecode-Ebene monitorenter- und monitorexit-Anweisungen ein.

Gründe für die Entstehung

In Multithread-Anwendungen ohne Synchronisation tritt eine Race Condition auf, wenn zwei Threads gleichzeitig dieselben Daten ändern, was zu unvorhersehbaren Ergebnissen führt. Synchronized wurde zum ersten und wichtigsten Werkzeug von Java zur Bekämpfung dieses Problems und bietet eine einfache deklarative Syntax, die jedem Entwickler zugänglich ist.

Wie funktioniert synchronized?

Der synchronized-Mechanismus basiert auf dem Konzept des Monitors — einem hochwertigen Synchronisationsprimitiv, das in jedes Java-Objekt eingebaut ist. Der Monitor wird einem Objekt zugeordnet, wenn erstmals ein synchronized-Block darauf verwendet wird.

Objektmonitor

Jedes Objekt in Java hat einen zugehörigen Monitor. Wenn ein Thread in einen synchronized-Block eintritt, erwirbt er den Monitor des Objekts. Wenn der Monitor bereits von einem anderen Thread gehalten wird, blockiert der Thread, bis er freigegeben wird. Im Bytecode entspricht dies dem Paar von monitorenter- und monitorexit-Anweisungen.

Sperrzustände (Biased Locking)

Die JVM optimiert synchronized über mehrere Ebenen: Biased Locking für Single-Thread-Zugriff, Lightweight Locking für geringe Konkurrenz und Heavyweight Locking für intensive Konkurrenz unter Beteiligung des Betriebssystems. Diese Ebenen verbessern die Leistung ohne Codeänderung.

java
class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

Happens-before-Regel

Synchronized stellt eine Happens-before-Beziehung her: Alle Aktionen in einem Thread vor dem Verlassen eines synchronized-Blocks sind für einen anderen Thread sichtbar, nachdem er einen auf demselben Objekt synchronisierten Block betreten hat. Dies garantiert nicht nur gegenseitigen Ausschluss, sondern auch Datenkonsistenz für alle Threads.

Synchronized-Methode vs. Block

Java bietet zwei Möglichkeiten, synchronized anzuwenden: auf Methodenebene und auf Blockebene. Die Wahl zwischen ihnen beeinflusst die Leistung und die Granularität der Synchronisation.

Synchronized-Methode

Das Markieren einer Methode mit dem synchronized-Modifikator synchronisiert sie automatisch auf der aktuellen Instanz (für Instanzmethoden) oder auf dem Class-Objekt (für statische Methoden). Dies ist der einfachste Weg, gegenseitigen Ausschluss zu gewährleisten, aber oft überzogen, wenn der kritische Abschnitt nur einen kleinen Teil der Methode ausmacht und der restliche Code keine Synchronisation benötigt.

Synchronized-Block

Ein synchronized-Block gibt präzise Kontrolle: Sie geben das Monitor-Objekt an und synchronisieren nur den notwendigen Codeabschnitt, während der Rest der Methode außerhalb der Sperre bleibt. Dies minimiert die Haltezeit des Monitors und verbessert die Gesamtleistung der Anwendung in einer Multithread-Umgebung, da andere Threads nicht auf die Freigabe des Monitors warten müssen, um nicht verwandten Code parallel auszuführen.

java
class DataProcessor {
    private final Object lock = new Object();

    public void process() {
        // Code außerhalb des kritischen Abschnitts - ohne Synchronisation
        prepareData()

        synchronized (lock) {
            // nur dieser Block ist geschützt
            updateSharedState()
        }

        // Fortsetzung ohne Sperre
        cleanup()
    }
}
KriteriumSynchronized-MethodeSynchronized-Block
Monitorthis (Instanz) oder Classbeliebiges Objekt
Granularitätgesamte Methodenur benötigter Code
Lesbarkeithochmittel
Leistungniedriger bei großen Methodenhöher bei kleinen kritischen Abschnitten

Synchronized in Android

In der Android-Entwicklung wird synchronized häufig zum Schutz von SharedPreferences, Datenbankzugriffen und UI-Komponenten verwendet. Die Verwendung im Hauptthread wird jedoch aufgrund des Risikos von Einfrieren der Benutzeroberfläche dringend vermieden.

Verwendung mit SharedPreferences

SharedPreferences in Android bietet grundlegende Threadsicherheit, aber bei Bearbeitung durch mehrere Threads über den Editor kann eine externe Synchronisation erforderlich sein. Ein synchronized-Block mit einem separaten Sperrobjekt garantiert die Konsistenz der Änderungen.

kotlin
class PreferencesManager(private val prefs: SharedPreferences) {
    private val lock = Any()

    fun writeToken(token: String) {
        synchronized (lock) {
            prefs.edit()
                .putString("auth_token", token)
                .apply()
        }
    }
}

Einschränkungen in Android-Anwendungen

Die Haupteinschränkung von synchronized auf Android ist die Thread-Blockierung. Im Gegensatz zu Coroutinen mit Mutex blockiert synchronized den gesamten Systemthread. Im Hauptthread verursacht dies ANR. In der modernen Android-Entwicklung wird empfohlen, synchronized durch Coroutinen (suspend Mutex) oder atomare Typen (AtomicInteger) zu ersetzen.

Alternativen zu synchronized

Modernes Java und Kotlin bieten mehrere Alternativen zu synchronized, die jeweils die gleichen Probleme mit weniger Einschränkungen oder besserer Leistung lösen.

Lock aus java.util.concurrent

Das Lock-Interface mit den Implementierungen ReentrantLock und ReadWriteLock bietet Timeouts, unterbrechbares Warten und mehrere Condition-Warteschlangen. Es ist flexibler als synchronized, erfordert aber explizite Freigabe in finally, was das Risiko von Fehlern bei vergessenem unlock erhöht.

Atomare Klassen

AtomicInteger, AtomicLong, AtomicReference und andere Klassen verwenden Lock-Free-Algorithmen auf Basis von CAS (Compare-And-Swap). Sie sind in Szenarien mit moderater Konkurrenz deutlich schneller als synchronized, da sie Threads nicht blockieren, sondern optimistische Wiederholungen ohne Kontextwechsel des OS-Kernels durchführen.

ThreadLocal und Threadsicherheit

ThreadLocal bietet einen alternativen Ansatz: Jede ThreadLocal-Variable ist innerhalb eines einzelnen Threads isoliert und erfordert keine Synchronisation für Lese- und Schreibzugriffe. Dies beseitigt vollständig die Notwendigkeit von synchronized für Daten, die nicht zwischen Threads geteilt werden sollen. ThreadLocal wird aktiv in Frameworks (Spring, Hibernate) zur Speicherung von Transaktionskontexten und Sitzungen verwendet.

Coroutinen und Compose-Ansatz

In Kotlin-Projekten für Android dient Mutex aus kotlinx.coroutines als Alternative zu synchronized. Es blockiert nicht den Betriebssystem-Thread, sondern setzt die Coroutine bis zur Freigabe der Sperre aus — dies ermöglicht eine effiziente Nutzung der Pool-Threads und vermeidet ANR bei langen Wartezeiten auf die Ressourcenfreigabe.

kotlin
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

val mutex = Mutex()
var counter = 0

suspend fun safeIncrement() {
    mutex.withLock {
        counter++
    }
}

Leistung von synchronized

Die Leistung von synchronized hat sich in den letzten Java-Versionen deutlich verändert. Früher galt es als „schwerer“ Mechanismus, aber moderne JVMs haben die meisten Gemeinkosten durch fortschrittliche JIT-Compiler-Optimierungen beseitigt. Sehen wir uns im Detail an, wie die virtuelle Maschine synchronisierten Code zur Laufzeit beschleunigt.

Biased Locking und Lock Coarsening

Der JIT-Compiler der JVM wendet mehrere Optimierungen an: Biased Locking eliminiert die Synchronisation, wenn die Sperre immer vom selben Thread erworben wird; Lock Coarsening fasst benachbarte synchronized-Blöcke zu einem zusammen; Lock Elimination entfernt die Synchronisation, wenn das Objekt nur von einem Thread zugänglich ist. Diese Optimierungen machen synchronized bei geringer Konkurrenz praktisch kostenlos.

Messung der Konkurrenz und Auswahl der Optimierung

Die JVM bestimmt den Konkurrenzgrad für jedes Objekt: Bei keiner Konkurrenz wird Biased Locking aktiviert; beim Auftreten eines zweiten Threads wechselt die Sperre in den Lightweight-Modus mit Spin-Warten; und nur bei längerem Warten eskaliert sie zu Heavyweight mit einem System-Mutex. Diese Eskalation erfolgt automatisch, und der Entwickler muss nicht manuell eine Strategie wählen.

Vergleich mit Lock und atomaren Klassen

In modernen Benchmarks (Java 17+) zeigt synchronized eine mit ReentrantLock vergleichbare Leistung bei niedriger und moderater Konkurrenz. Bei hoher Konkurrenz kann Lock dank einer effizienteren Warteschlange mit Timeout- und Interrupt-Unterstützung Vorteile haben. Für hochlastige Systeme mit konstanter Konkurrenz bietet ReentrantLock mit Fair-Mode ein vorhersehbareres Verhalten.

Atomare Klassen (AtomicInteger, AtomicReference) bleiben dank der Lock-Free-CAS-Implementierung die schnellsten für einfache Zähler und Flags. Sie blockieren Threads überhaupt nicht — bei Konflikten wiederholt die Operation einfach in einer Schleife. Dies ergibt einen 3- bis 5-fachen Leistungsgewinn im Vergleich zu synchronized bei Zählererhöhungsoperationen mit 4-8 Threads.

Häufig gestellte Fragen

Was ist der Unterschied zwischen synchronized und volatile?

Synchronized bietet sowohl gegenseitigen Ausschluss als auch Sichtbarkeit. Volatile garantiert nur die Sichtbarkeit von Änderungen — das Schreiben in eine volatile-Variable ist für alle Threads sichtbar, verhindert aber nicht die gleichzeitige Änderung, schützt also nicht vor Race Conditions.

Kann synchronized einen Deadlock verursachen?

Ja, Deadlock ist bei verschachtelter Synchronisation mit unterschiedlicher Monitor-Reihenfolge möglich. Beispielsweise ruft ein Thread synchronized(a) { synchronized(b) } auf, während ein anderer synchronized(b) { synchronized(a) } aufruft. Vermeiden Sie verschachtelte synchronized-Blöcke oder legen Sie eine konsistente Monitor-Reihenfolge fest.

Was ist ein Monitor in Java?

Ein Monitor ist ein Synchronisationsmechanismus, der mit jedem Java-Objekt verbunden ist. Er garantiert, dass nur ein Thread synchronized-Code auf diesem Objekt ausführt. Der Monitor umfasst eine Sperre, eine Warteschlange und einen Pool von Threads, die auf Benachrichtigung über wait/notify warten.

Ist Lock schneller als synchronized?

In modernen Java-Versionen (17+) steht synchronized Lock in Bezug auf die Leistung dank JIT-Optimierungen (Biased Locking, Lock Coarsening) nicht nach. Lock wird nicht wegen der Geschwindigkeit bevorzugt, sondern wegen zusätzlicher Funktionen: Timeouts, unterbrechbares Warten und mehrere Condition-Warteschlangen.

Wie funktioniert synchronized bei statischen Methoden?

Eine statische synchronized-Methode verwendet den Monitor des Class-Objekts der gegebenen Klasse, nicht der Instanz. Das bedeutet, dass die Synchronisation für alle Instanzen der Klasse gilt. Nicht-statische und statische synchronized-Methoden verwenden unterschiedliche Monitore und blockieren sich nicht gegenseitig.

Zusammenfassung

  • Synchronized — integrierter Java-Synchronisationsmechanismus auf Basis von Monitoren.
  • Objektmonitor — interne JVM-Struktur, die gegenseitigen Ausschluss gewährleistet.
  • Wait/notify-Methoden werden nur innerhalb von synchronized-Blöcken oder -Methoden verwendet.
  • Synchronized-Block ist aufgrund feinerer Synchronisationsgranularität einer Methode vorzuziehen.
  • Happens-before garantiert die Sichtbarkeit von Änderungen zwischen Threads bei Synchronisation auf demselben Objekt.
  • Deadlock — das Hauptrisiko bei verschachtelter Synchronisation mit unterschiedlicher Monitor-Reihenfolge.
  • Alternativen — Lock, atomare Klassen und Coroutinen mit Suspending Mutex.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch