JMM: ошибки многопоточного доступа к данным | OTUS >
Не смотрите на этот баннер
Не смотрите на этот баннер
Если не хотите получить скидку 5% на все курсы. 19 октября акция закончится — выбирайте курс с выгодой уже сейчас
Если не хотите получить скидку 5% на все курсы. 19 октября акция закончится — выбирайте курс с выгодой уже сейчас
Получить скидку 5%

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.

Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто
Распродажа ноябрьских курсов
Распродажа ноябрьских курсов
Выберите программу уже сейчас, и получите скидку 10%. Главное, успеть до 25 октября, иначе бонус сгорит
Выберите программу уже сейчас, и получите скидку 10%. Главное, успеть до 25 октября, иначе бонус сгорит