JMM: ошибки многопоточного доступа к данным | OTUS
⚡ Подписка на курсы OTUS!
Интенсивная прокачка навыков для IT-специалистов!
Подробнее

Курсы

Программирование
Team Lead Архитектура и шаблоны проектирования Разработчик IoT C# Developer. Professional PostgreSQL Подготовка к сертификации Oracle Java Programmer (OCAJP) C# ASP.NET Core разработчик
-5%
Kotlin Backend Developer
-8%
iOS Developer. Professional
-8%
Symfony Framework Unity Game Developer. Basic JavaScript Developer. Professional Android Developer. Basic JavaScript Developer. Basic Java Developer. Professional Highload Architect Reverse-Engineering. Professional Java Developer. Basic PHP Developer. Professional Алгоритмы и структуры данных Framework Laravel Cloud Solution Architecture Vue.js разработчик Интенсив «Оптимизация в Java» Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Супер-интенсив "Tarantool" PHP Developer. Basic
Инфраструктура
Мониторинг и логирование: Zabbix, Prometheus, ELK Дизайн сетей ЦОД Разработчик IoT PostgreSQL Экспресс-курс "Версионирование и командная работа с помощью Git"
-30%
Экспресс-курс «Введение в непрерывную поставку на базе Docker» Базы данных Reverse-Engineering. Professional Administrator Linux. Professional Network engineer Cloud Solution Architecture Внедрение и работа в DevSecOps Супер-практикум по работе с протоколом BGP Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Супер-интенсив «СУБД в высоконагруженных системах» Супер-интенсив "Tarantool" Network engineer. Basic
Корпоративные курсы
Безопасность веб-приложений IT-Recruiter Дизайн сетей ЦОД Компьютерное зрение Разработчик IoT Вебинар CERTIPORT Machine Learning. Professional
-6%
NoSQL Пентест. Практика тестирования на проникновение Java QA Engineer. Базовый курс Руководитель поддержки пользователей в IT
-8%
SRE практики и инструменты Cloud Solution Architecture Внедрение и работа в DevSecOps Супер-практикум по работе с протоколом BGP Infrastructure as a code Супер-практикум по использованию и настройке GIT Промышленный ML на больших данных Экспресс-курс «CI/CD или Непрерывная поставка с Docker и Kubernetes» BPMN: Моделирование бизнес-процессов Основы Windows Server
Специализации Курсы в разработке Подготовительные курсы Подписка
+7 499 938-92-02

JMM: ошибки многопоточного доступа к данным

Java_Deep_9-5020-55bf9f.10_site.png

Принято считать, что многопоточность (multithreading) одна из самых сложных тем в программировании. В первой заметке мы постарались ответить на вопрос, почему так много разработчиков делают ошибки при создании приложений, которые работают более чем в одном потоке. В этой заметке разберём типы ошибок многопоточного доступа к данным: race condition и memory consistency errors. Но, перед тем как обсуждать ошибки доступа, давайте сначала разберёмся, что такое многопоточный доступ к данным.

В какой именно ситуации можно получить такие ошибки?

Мы уже упоминали, что поток в Java — это объект. У любого объекта есть класс. В классе могут быть методы и переменные. Представьте, что у вас есть класс-наследник от Thread, в котором вы в одной из переменных храните ссылку на массив. И этот массив вы получаете в конструкторе класса.

Пусть теперь, в runtime вы создаёте два объекта рассмотренного выше класса и передаёте в оба один и тот же массив. К элементам этого массива вы можете обращаться в методах run() ваших объектов. Одновременно. Из разных потоков исполнения. Вот это и есть многопоточный доступ к данным, которые хранит массив. Например, один поток может писать что-то в массив, а другой читать из него.

Ошибки многопоточного доступа

Рассмотрим теперь ситуацию, когда два рассмотренных выше потока собираются увеличить значение числа, которое записано в первой ячейке массива. Последовательность событий такая: — первый поток прочитал значение и увеличил его, — второй поток прочитал то же значение, — первый записал новое, — второй увеличил значение и записал его.

В результате вместо ожидаемого увеличения значения на 2 мы получим увеличение на 1, так как результат работы первого потока был «перетёрт» результатом работы второго. Такая ситуация происходит из-за неатомарности операции увеличения значения числа. И является разновидностью ошибки многопоточного доступа — race condition.

Вторая возможная ошибка многопоточного доступа — memory consistency error происходит из-за того, что разные потоки могут быть физически исполнены на различных процессорах вашего компьютера. Каждый процессор может закэшировать значение переменной у себя, не записывая её в общую память. В результате разные потоки могут видеть в одно и тоже время разное значение переменной.

Описанные выше проблемы призвана решить Java Memory Model. Если не знаете, что это такое и как именно она может помочь Java-разработчику, спрашивайте в комментариях!

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
2 комментария
0

Спрашиваю!

0

Тут бы помогла картинка, где несколько ядер, их "личные" кэши L1-L2 и общий L3. Т.е. другие ядра смогут узнать об изменении только когда оно дойдет до L3.

Для комментирования необходимо авторизоваться