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é:
- 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.
- Čakanie a oznámenie (Waiting and Notification): Monitor obsahuje sadu súvisiacich metód
wait(),notify()anotifyAll(). 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:
monitorenterinštrukcia: Vykonáva sa pri vstupe do synchronizovaného bloku alebo metódy. Pokúsi sa získať monitor objektu.monitorexitinš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. |