Разбор synchronized в рекурсивном методе

Это Java-код, несмотря на метку kotlin. synchronized реентерабелен: рекурсивный вызов не заблокирует собственный поток, и value станет равным 10.

Короткий ответ

Что ответить на собеседовании

Это 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 имеют разные мониторы.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее