Sobes.tech
Middle+

Как работи механизмът за синхронизация 'synchronized' в Java зад кулисите?

sobes.tech AI

Отговор от AI

Механизмът synchronized в Java се основава на концепцията за монитори (monitor objects). Всяко обект в Java е асоцииран с монитор.

Когато нишка влезе в синхронизирана блок или метод, тя се опитва да вземе съответния монитор на обекта. Ако мониторът е свободен, нишката го взема и продължава изпълнението. Ако мониторът е зает от друга нишка, текущата нишка се блокира и преминава в състояние на изчакване, докато мониторът не бъде освободен.

Когато нишката напусне синхронизирания блок или метод (успешно или чрез изключение), тя освобождава монитора.

Вътре в монитора са реализирани:

  1. Взаимно изключване (Mutual Exclusion): Само една нишка може да притежава монитора на обекта в даден момент. Това гарантира, че само една нишка може да изпълнява синхронизирания код за дадения обект.
  2. Изчакване и уведомяване (Waiting and Notification): Мониторът включва набор от свързани методи wait(), notify() и notifyAll(). Тези методи позволяват на нишките, притежаващи монитора, временно да го освободят и да преминат в състояние на изчакване, а след това да бъдат уведомени от други нишки за възможността да продължат работата си.

Реализацията под капака включва:

  • monitorenter инструкция: Изпълнява се при влизане в синхронизирания блок или метод. Опитва се да вземе монитора на обекта.
  • monitorexit инструкция: Изпълнява се при излизане от синхронизирания блок или метод (както при нормално завършване, така и при изключение). Освобождава монитора на обекта.

Тези инструкции са част от байт-кода на Java и се обработват от виртуалната машина Java (JVM). JVM използва нативни механизми на операционната система (например mutexes, semaphores) за управление на мониторите и блокирането/разблокирането на нишки.

Завладяването на монитора може да бъде реализирано на ниво обект (за instance methods и блокове) или на ниво клас (за static methods и блокове), като се използва обектът Class като блокировка.

Пример за използване:

public class Counter {
    private int count = 0;

    public synchronized void increment() { // Синхронизирана метода
        count++;
    }

    public void decrement() {
        synchronized (this) { // Синхронизирана блок
            count--;
        }
    }

    public static synchronized void staticMethod() { // Синхронизирана статична метода
        // ...
    }
}

Таблица на методите на класа Object, свързани с монитори:

Метод Описание
wait() Нит, притежаваща монитор, временно го освобождава и преминава в състояние на изчакване.
notify() Уведомява една от чакащите нишки, че може да се опита да вземе монитора и да продължи работата си.
notifyAll() Уведомява всички чакащи нишки.