Что такое race condition
Что проверяют
Понимаете ли вы, что дело в непредсказуемом порядке, а не в самой многопоточности, и знаете ли, как это лечится в Android.
Как отвечать
Состояние гонки это ситуация, когда результат зависит от порядка выполнения параллельных потоков или корутин, а порядок не гарантирован. Программа работает правильно почти всегда и ломается редко, поэтому такие дефекты тяжело воспроизвести.
Два классических вида:
- прочитал, изменил, записал:
counter++это три операции. Две корутины читают одно значение и записывают одинаковый результат, одно увеличение теряется; - проверил и сделал: проверили, что записи нет, и вставили. Между проверкой и вставкой то же самое успел сделать другой поток, получилось два дубля.
Отдельно стоит назвать гонку за данными (data race): конкурентный доступ к одной памяти без синхронизации, где хотя бы один участник пишет. Это частный случай, но не синоним: гонка возможна и при атомарных операциях, если непоследовательна логика целиком.
Типичные проявления в Android: двойное нажатие кнопки создаёт две записи; данные обновляются из нескольких корутин на разных диспетчерах; результат устаревшего запроса приходит позже свежего и перезаписывает состояние; обращение к элементам интерфейса не из главного потока.
Как лечится, по убыванию предпочтительности:
- неизменяемость и однонаправленный поток данных: состояние экрана в одном
StateFlow, обновление черезupdate { }, который делает атомарное сравнение с обменом; - ограничение состояния одним потоком: обработка на выделенном диспетчере, привязка интерфейса к главному потоку;
Mutexиз корутин там, где нужна составная операция. ИменноMutex, а неsynchronized: последний блокирует поток, а не приостанавливает корутину;- атомарные типы для счётчиков;
- идемпотентность и ограничения в базе: уникальный индекс не даст вставить дубль, что бы ни делал код.
Где спотыкаются
Считают, что проблема исчезает при synchronized на каждом методе, забывая про составные операции.
Используют synchronized внутри корутины и блокируют поток.
Не защищают от повторного нажатия кнопки.
Игнорируют гонку ответов при быстрой смене экрана.