Вопрос проверяет умение проектировать тонкую синхронизацию для повышения масштабируемости.
Блокировка по ID реализуется через отдельный объект синхронизации для каждого ключа.
Вместо одного глобального synchronized используется мапа локов.
Каждый ID блокируется независимо.
Это повышает параллелизм.
Важно корректно управлять жизненным циклом локов.
Глобальная блокировка быстро становится узким местом.
Нужно синхронизировать доступ не ко всей логике, а только к конкретному ресурсу.
Использование мапы локов:
Map<Long, Object> locks = new ConcurrentHashMap<>();
Object lock = locks.computeIfAbsent(id, k -> new Object());
synchronized (lock) {
// критическая секция для конкретного id
}
Каждый id получает свой lock
Потоки с разными id не блокируют друг друга
ConcurrentHashMap потокобезопасен
Проблема:
мапа может бесконечно расти
Решения:
удалять lock после использования
использовать WeakReference
применять ReentrantLock с тайм-аутом
Блокировка по ID позволяет повысить масштабируемость, но требует аккуратного управления синхронизирующими объектами.