Какие проблемы многопоточности существуют в Java
Javaасинхронностьмногопоточностьпроблемы многопоточностистатические методы
Что проверяют
Можете ли вы назвать проблемы по именам и объяснить разницу между ними, а не просто сказать «гонки и дедлоки».
Как отвечать
- гонка данных: несколько потоков обращаются к одной переменной без синхронизации, и хотя бы один пишет. Результат зависит от планировщика, а из-за модели памяти изменение может быть не видно другому потоку вообще никогда;
- состояние гонки: логическая ошибка порядка. Проверили условие, а к моменту действия оно перестало быть верным. Каждая операция может быть атомарной, а сценарий всё равно сломан. Классика это «проверить и вставить» в карту;
- взаимная блокировка: два потока держат по ресурсу и ждут ресурс друг друга. Лечится единым порядком захвата или захватом по таймауту;
- активная блокировка: потоки не заблокированы, но бесконечно уступают друг другу и не продвигаются;
- голодание: поток никогда не получает ресурс, потому что его вечно опережают;
- проблемы видимости: значение осело в кэше ядра или в регистре, и другой поток читает устаревшее. Отсюда
volatileи правило happens-before; - ложное разделение строки кэша: две независимые переменные попали в одну строку кэша, и потоки мешают друг другу, хотя логически не пересекаются;
- истощение пула: все потоки пула заняты ожиданием, и работа встала.
Ключевая мысль, которую стоит произнести: источник почти всех проблем это разделяемое изменяемое состояние. Неизменяемые объекты, локальные переменные и передача данных через очередь снимают вопрос целиком.
Где спотыкаются
Не различают гонку данных и состояние гонки.
Считают, что synchronized решает все проблемы, включая логические.
Не знают про видимость и удивляются, что поток не видит изменение.
Не пользуются детектором проблем: тестами на конкурентность, статическим анализом, стресс-прогонами.