Выбор ответа Senior Потоки и Java Memory Model обновлено
False sharing
Вопрос
Два потока часто инкрементят два разных volatile long поля одного объекта, и это неожиданно медленно. В чём вероятная причина?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: False sharing: поля в одной кеш-линии, и ядра отбирают её друг у друга. Кеш когерентен по линиям примерно по 64 байта.
Варианты ответа
volatileделает каждую операцию синхронизированной на мониторе объекта- False sharing: поля в одной кеш-линии, и ядра отбирают её друг у другаправильный ответ
- JIT отключает оптимизации для полей типа long, если они volatile
- Поля long читаются за две операции по 32 бита, и каждая ждёт другую
Разбор
Кеш когерентен по линиям примерно по 64 байта. Если два горячих поля в одной линии, запись одного ядра инвалидирует линию у другого, хотя логически данные разные. Лечится разнесением полей (padding, @jdk.internal.vm.annotation.Contended внутри JDK, так сделано в LongAdder). volatile не берёт монитор. Чтение volatile long атомарно по спецификации.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.