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

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.

Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто