Sobes.tech
Middle+

Jak funguje mechanismus synchronizace 'synchronized' v jazyce Java na pozadí?

sobes.tech AI

Odpověď od AI

Mechanismus synchronized v Javě je založen na konceptu monitorů (monitor objects). Každý objekt v Javě má přiřazen monitor.

Když vlákno vstoupí do synchronizovaného bloku nebo metody, pokusí se získat odpovídající monitor objektu. Pokud je monitor volný, vlákno ho získá a pokračuje ve vykonávání. Pokud je monitor obsazen jiným vláknem, aktuální vlákno se zablokuje a přejde do stavu čekání, dokud monitor neuvolní.

Když vlákno opustí synchronizovaný blok nebo metodu (ať už úspěšně, nebo vyhozením výjimky), monitor uvolní.

Uvnitř monitoru jsou implementovány:

  1. Vzájemné vyloučení (Mutual Exclusion): Pouze jedno vlákno může vlastnit monitor objektu v daném čase. To zaručuje, že pouze jedno vlákno může vykonávat synchronizovaný kód pro daný objekt.
  2. Čekání a oznámení (Waiting and Notification): Monitor obsahuje sadu souvisejících metod wait(), notify() a notifyAll(). Tyto metody umožňují vláknům, která vlastní monitor, dočasně ho uvolnit a přejít do stavu čekání, a poté být upozorněna jinými vlákny o možnosti pokračovat v práci.

Implementace na pozadí zahrnuje:

  • monitorenter instrukce: Provádí se při vstupu do synchronizovaného bloku nebo metody. Pokusí se získat monitor objektu.
  • monitorexit instrukce: Provádí se při opuštění synchronizovaného bloku nebo metody (jak při normálním ukončení, tak při výjimce). Uvolní monitor objektu.

Tyto instrukce jsou součástí byte-kódu Javy a jsou zpracovávány virtuální JVM. JVM používá nativní mechanismy operačního systému (například mutexy, semafory) k řízení monitorů a blokování/odblokování vláken.

Získání monitoru může být realizováno na úrovni objektu (pro instance metody a bloky) nebo na úrovni třídy (pro static metody a bloky), přičemž se používá objekt Class jako zámek.

Příklad použití:

public class Counter {
    private int count = 0;

    public synchronized void increment() { // Synchronizovaná metoda
        count++;
    }

    public void decrement() {
        synchronized (this) { // Synchronizovaný blok
            count--;
        }
    }

    public static synchronized void staticMethod() { // Synchronizovaná statická metoda
        // ...
    }
}

Tabulka metod třídy Object spojených s monitory:

Metoda Popis
wait() Vlákno, které vlastní monitor, jej dočasně uvolní a přejde do stavu čekání.
notify() Upozorní jedno z čekajících vláken, že může pokusit se získat monitor a pokračovat v práci.
notifyAll() Upozorní všechna čekající vlákna.