Это Java-код, несмотря на метку kotlin. synchronized реентерабелен: рекурсивный вызов не заблокирует собственный поток, и value станет равным 10.
Разбор synchronized в рекурсивном методе
Это Java-код, несмотря на метку kotlin. synchronized реентерабелен: рекурсивный вызов не заблокирует собственный поток, и value станет равным 10.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо внимательно изучить представленный фрагмент и выявить скрытые подводные камни его работы.
public class Incrementor {
int value = 0;
public synchronized void inc() {
if (value < 10) {
value++;
inc();
}
}
}
new Incrementor().inc();
Ответ
Это Java-код, несмотря на метку kotlin. synchronized реентерабелен: рекурсивный вызов не заблокирует собственный поток, и value станет равным 10.
Один поток может повторно захватить монитор того же объекта. Здесь значение увеличивается от 0 до 10, после чего рекурсия останавливается; при раскрутке вызовов монитор постепенно освобождается. Другой поток не войдёт в inc того же экземпляра до выхода из внешнего вызова.
Сам по себе пример ничего не печатает. Доступ к value из другого потока вне той же синхронизации не становится безопасным автоматически. Для большого или неконтролируемого предела рекурсия создаёт риск переполнения стека; простой цикл внутри synchronized понятнее и дешевле. Разные экземпляры Incrementor имеют разные мониторы.