Ответ
В скобках у оператора synchronized указывается объект-монитор (lock object), чья внутренняя блокировка (intrinsic lock) используется для синхронизации доступа к блоку кода или методу.
Зачем это нужно? Чтобы явно задать объект, на котором будет происходить синхронизация, обеспечивая тонкий контроль над параллелизмом и избегая неявных проблем.
Примеры:
public class Example {
private final Object lock = new Object(); // Специальный объект-монитор
private int count = 0;
public void safeIncrement() {
synchronized(lock) { // Синхронизация на объекте lock, а не на 'this'
count++;
}
}
}
Ключевые моменты:
- Для
synchronizedметодов монитором неявно выступаетthis(для нестатических) или объект классаClass(для статических). - Использование отдельного приватного объекта (
private final Object lock) — это best practice. Это предотвращает:- Внешнюю блокировку: Клиентский код не может синхронизироваться на вашем объекте, вызвав
synchronized(exampleInstance), что могло бы привести к deadlock. - Ненужную конкуренцию: Разные блоки кода можно синхронизировать на разных объектах, увеличивая параллелизм.
- Внешнюю блокировку: Клиентский код не может синхронизироваться на вашем объекте, вызвав
- Объект-монитор должен быть
final, чтобы ссылка на него не могла измениться, иначе синхронизация будет нарушена.