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:
- 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.
- Čekání a oznámení (Waiting and Notification): Monitor obsahuje sadu souvisejících metod
wait(),notify()anotifyAll(). 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:
monitorenterinstrukce: Provádí se při vstupu do synchronizovaného bloku nebo metody. Pokusí se získat monitor objektu.monitorexitinstrukce: 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. |