Когда несколько переменных обновляются и читаются вместе, возникает опасность несогласованных изменений:
Был объект: точка (0, 0)
▫️Поток 1 хочет обновить координаты на (1, 1). Сначала обновляет X, потом Y.
▫️Поток 2 врывается в середине процесса и читает (0, 1).
Чтобы такого не было, используются критические секции: участки кода с ограниченным доступом. JDK предлагает 5 вариантов организовать критическую секцию:
🔸 synchronized
🔸 ReentrantLock
🔸 ReentrantReadWriteLock
🔸 StampedLock
🔸 Semaphore
Три первых класса встречаются чаще всего, поэтому сравним их между собой.
synchronized и ReentrantLock дают эксклюзивный доступ потока к коду. Чтение объекта никогда не происходит одновременно с обновлением.
ReadWriteLock предлагает такую идею: если переменная сейчас не обновляется, то нет смысла ограничивать количество читающих потоков. Для этого в ReadWriteLock есть два вида локов:
🔹 Для чтения:
readLock()
🔹 Для записи: writeLock()
Выбираем реализациюИзвестно, что переменные читаются в 5 раз чаще, чем обновляются.
▫️ ReetrantLock и synchronized пускают только один поток в критическую секцию
▫️ ReadWriteLock запускает несколько потоков на чтение
Делаем прогноз, что ReadWriteLock разгромно победит остальные варианты.
Эксперимент
Измерим пропускную способность каждой реализации. Попробуем разную нагрузку и соотношение чтения-записи. Результаты сведём в график.
По горизонтали отметим разные кейсы. 5-1 означает, что в один момент 5 потоков читают значения, и 1 поток обновляет переменную.
По вертикали - пропускная способность. Чем выше график, тем лучше
Сам график - внизу поста⬇️
Результаты
Шок-контент! synchronized и ReetrantLock работают в 2-3 раза лучше, чем ReadWriteLock. Только в ситуации 10-1 его скорость немного приближается к конкурентам.
Почему ReadWriteLock проиграл?
Если кратко - сложная и неоптимальная реализация. ReetrantLock и synchronized используют простые конструкции и выигрывают у специализированного ReadWriteLock.
Логичен такой результат? Нет
Очевиден из чтения документации? Нет
Подобных ситуаций в JDK не так много. Большинство классов хорошо спроектированы, и при правильном использовании работают отлично.
————————
На курс многопоточки осталось 3 места. Старт уже в следующий понедельник.