Как работи механизмът за синхронизация 'synchronized' в Java зад кулисите?
sobes.tech AI
Отговор от AI
Механизмът synchronized в Java се основава на концепцията за монитори (monitor objects). Всяко обект в Java е асоцииран с монитор.
Когато нишка влезе в синхронизирана блок или метод, тя се опитва да вземе съответния монитор на обекта. Ако мониторът е свободен, нишката го взема и продължава изпълнението. Ако мониторът е зает от друга нишка, текущата нишка се блокира и преминава в състояние на изчакване, докато мониторът не бъде освободен.
Когато нишката напусне синхронизирания блок или метод (успешно или чрез изключение), тя освобождава монитора.
Вътре в монитора са реализирани:
- Взаимно изключване (Mutual Exclusion): Само една нишка може да притежава монитора на обекта в даден момент. Това гарантира, че само една нишка може да изпълнява синхронизирания код за дадения обект.
- Изчакване и уведомяване (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() |
Уведомява всички чакащи нишки. |