Sobes.tech
Middle+

Ako funguje mechanizmus synchronizácie 'synchronized' v jazyku Java na pozadí?

sobes.tech AI

Odpoveď od AI

Mechanizmus synchronized v Jave je založen na koncepte monitorov (monitor objects). Každý objekt v Jave je spojený s monitorom.

Keď vlákno vstúpi do synchronizovaného bloku alebo metódy, pokúsi sa získať príslušný monitor objektu. Ak je monitor voľný, vlákno ho získa a pokračuje vo vykonávaní. Ak je monitor obsadený iným vláknom, aktuálne vlákno sa zablokuje a prejde do stavu čakania, kým monitor nebude uvoľnený.

Keď vlákno opustí synchronizovaný blok alebo metódu (úspešne alebo výnimkou), uvoľní monitor.

Vnútri monitoru sú implementované:

  1. Vzájomné vylúčenie (Mutual Exclusion): Len jedno vlákno môže vlastniť monitor objektu v danom čase. To zaručuje, že len jedno vlákno môže vykonávať synchronizovaný kód pre daný objekt.
  2. Čakanie a oznámenie (Waiting and Notification): Monitor obsahuje sadu súvisiacich metód wait(), notify() a notifyAll(). Tieto metódy umožňujú vláknam, ktoré vlastnia monitor, dočasne ho uvoľniť a prejsť do stavu čakania, a následne byť upozornené inými vláknami o možnosti pokračovať v práci.

Implementácia na pozadí zahŕňa:

  • monitorenter inštrukcia: Vykonáva sa pri vstupe do synchronizovaného bloku alebo metódy. Pokúsi sa získať monitor objektu.
  • monitorexit inštrukcia: Vykonáva sa pri opustení synchronizovaného bloku alebo metódy (ako pri normálnom ukončení, tak pri výnimke). Uvoľní monitor objektu.

Tieto inštrukcie sú súčasťou byte-kódu Javy a sú spracovávané virtuálnou JVM. JVM používa nativné mechanizmy operačného systému (napríklad mutexy, semafory) na riadenie monitorov a blokovanie/odblokovanie vlákien.

Získanie monitoru môže byť realizované na úrovni objektu (pre instance methods a bloky) alebo na úrovni triedy (pre static methods a bloky), pričom sa používa objekt Class ako zámok.

Príklad použitia:

public class Counter {
    private int count = 0;

    public synchronized void increment() { // Synchronizovaná metóda
        count++;
    }

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

    public static synchronized void staticMethod() { // Synchronizovaná statická metóda
        // ...
    }
}

Tabuľka metód triedy Object, spojených s monitorami:

Metóda Popis
wait() Vlákno, ktoré vlastní monitor, dočasne ho uvoľní a prejde do stavu čakania.
notify() Upozorní jedno z čakajúcich vlákien, že môže pokúsiť sa získať monitor a pokračovať v práci.
notifyAll() Upozorní všetky čakajúce vlákna.