Вопрос проверяет понимание механизмов синхронизации в Java для управления доступом к общим ресурсам в многопоточной среде.
В Java ключевое слово synchronized — основной инструмент для обеспечения потокобезопасности при работе с общими ресурсами. Оно гарантирует, что только один поток в данный момент может выполнять синхронизированный участок кода, предотвращая состояние гонки (race condition) и нарушение целостности данных.
Когда модификатор synchronized применяется к методу, весь метод становится критической секцией. Для нестатических методов блокировка захватывается на объекте, у которого вызван метод (т.е. на this). Для статических методов блокировка захватывается на объекте класса Class, связанном с этим классом. Это простой, но иногда избыточный подход, так как блокируется весь метод, даже если безопасность требуется только для нескольких операций внутри него.
public class Counter {
private int value = 0;
// Синхронизированный метод
public synchronized void increment() {
value++; // Вся операция защищена
}
}Синхронизированный блок позволяет явно указать объект-монитор (любой объект) и ограничить область синхронизации только необходимыми строками кода. Это даёт больше гибкости и может значительно повысить производительность, так как другие потоки могут работать с объектом, пока заблокирована только небольшая часть.
public class FineGrainedCounter {
private int value = 0;
private final Object lock = new Object(); // Специальный объект для блокировки
public void increment() {
// Несинхронизированные операции могут выполняться здесь параллельно
synchronized(lock) { // Блокируем только критическую секцию
value++;
}
}
}this или Class.На практике синхронизированные блоки часто предпочтительнее для сложных объектов, где нужно минимизировать contention (соревнование за блокировку). Синхронизированные методы хорошо подходят для простых классов или когда весь метод действительно является критической секцией.
Вывод: Используйте синхронизированный метод для простых случаев, когда безопасность требуется на уровне всего метода. Для оптимизации производительности и более точного контроля над блокировками применяйте синхронизированный блок, явно указывая объект-монитор и ограничивая критическую секцию минимально необходимым кодом.