Sobes.tech
Middle+

Cum funcționează mecanismul de sincronizare 'synchronized' în Java în spate?

sobes.tech AI

Răspuns de la AI

Mecanismul synchronized în Java se bazează pe conceptul de monitoare (obiecte monitor). Fiecărui obiect în Java îi este asociat un monitor.

Când un fir de execuție intră într-un bloc sau metodă sincronizată, încearcă să obțină monitorul obiectului respectiv. Dacă monitorul este liber, firul îl preia și continuă execuția. Dacă monitorul este ocupat de alt fir, firul curent se blochează și trece în stare de așteptare până când monitorul este eliberat.

În interiorul monitorului sunt implementate:

  1. Excludere mutuală (Mutual Exclusion): Doar un fir poate deține monitorul unui obiect într-un moment dat. Acest lucru garantează că doar un fir poate executa cod sincronizat pentru acel obiect.
  2. Așteptare și notificare (Waiting and Notification): Monitorul include un set de metode asociate wait(), notify() și notifyAll(). Aceste metode permit firelor care dețin monitorul să îl elibereze temporar și să treacă în stare de așteptare, fiind ulterior notificate de alte fire despre posibilitatea de a continua.

Implementarea la nivel de bază include:

  • Instrucțiunea monitorenter: Se execută la intrarea într-un bloc sau metodă sincronizată. Încearcă să obțină monitorul obiectului.
  • Instrucțiunea monitorexit: Se execută la ieșirea dintr-un bloc sau metodă sincronizată (fie prin finalizare normală, fie prin excepție). Eliberează monitorul obiectului.

Aceste instrucțiuni fac parte din codul byte Java și sunt gestionate de mașina virtuală Java (JVM). JVM folosește mecanisme native ale sistemului de operare (cum ar fi mutex-uri, semafoare) pentru gestionarea monitorilor și blocarea/deblocarea firelor.

Preluarea monitorului poate fi implementată la nivel de obiect (pentru metode și blocuri de instanță) sau la nivel de clasă (pentru metode și blocuri statice), folosind obiectul Class ca blocare.

Exemplu de utilizare:

public class Counter {
    private int count = 0;

    public synchronized void increment() { // Metodă sincronizată
        count++;
    }

    public void decrement() {
        synchronized (this) { // Bloc sincronizat
            count--;
        }
    }

    public static synchronized void staticMethod() { // Metodă statică sincronizată
        // ...
    }
}

Tabelul metodelor clasei Object, legate de monitoare:

Metodă Descriere
wait() Firul care deține monitorul îl eliberează temporar și trece în stare de așteptare.
notify() Notifică unul dintre firele în așteptare că poate încerca să obțină monitorul și să continue.
notifyAll() Notifică toate firele în așteptare.