Читаем Многопоточное программирование в Java полностью

Атомарные действия не могут перемешиваться, поэтому их можно использовать, не опасаясь интерференции потоков.

Однако это не устраняет необходимости синхронизации атомарных действий, так как возможны ошибки согласованности памяти.

В целях повышения производительности среда выполнения JRE сохраняет локальные копии переменных для каждого потока, который на них ссылается.

Такие «локальные» копии переменных работают как кэш и помогают потоку избежать обращения к главной памяти каждый раз, когда требуется получить значение переменной.

Поэтому если один поток изменит значение переменной, то другой поток может не увидеть это изменение, так как будет считывать значение из своего кэша. Это и будет ошибкой согласованности памяти

Однако если переменная помечена как volatile, то, когда бы поток не считывал значение, он будет считывать ее текущее значение.

Использование volatile переменных, не только для long и double, снижает риск ошибок согласованности памяти, поскольку любая запись в volatile переменную устанавливает связь между событиями и последующими чтениями этой же переменной.

Это означает, что изменения в volatile переменной всегда видны для других потоков.

Опять же речь идет только об операциях чтения и записи.

Резюмируя, объявление блока кода синхронным обеспечивает для кода атомарность и видимость.

Атомарность значит, что только один поток одновременно может выполнять код, защищенный данным объектом-монитором (блокировкой), позволяя предотвратить многочисленные потоки от столкновений друг с другом во время обновления общего состояния.

Видимость связана с особенностями кэширования памяти и оптимизацией программы в процессе компилирования.

Обычно потоки могут свободно кэшировать значения для переменных так, чтобы они не обязательно сразу же были бы видны другим потокам, но, если разработчик использовал синхронизацию, во время выполнения будет проверяться, что обновления переменных, выполненные одним потоком до выхода из синхронизированного блока, сразу же будут видны другому потоку, когда он будет входить в синхронизированный блок, защищенный тем же монитором (блокировкой).

Подобное правило видимости существует и для переменных volatile.

Живучесть Liveness


Теперь, давайте рассмотрим фундаментальное свойство корректности многопоточных программ, которое называется LIVENESS или живучесть.

Когда вы пишете не многопоточную, а последовательную программу, и в ней есть ошибка, вы запускаете ее, и на экране ничего не появляется.

Вы ждете, а затем выясняете, например, что у вас в коде есть бесконечный цикл.

И тогда вы исправляете ошибку.

К сожалению, в многопоточных программах есть много других способов получить этот эффект пустого экрана.

Один из них — это DEADLOCK или взаимная блокировка.

Это мы уже видели в случае операции join.



Если два потока соединяются друг с другом, они создают цикл взаимоблокировки, и по этой причине программа не завершается.

Это не бесконечный цикл в обычном понимании, это два потока, заблокированных друг от друга на неопределенный срок.

Существуют и другие способы получения взаимоблокировки.

Например, если поток T1 выполняет синхронизированную операцию на объекте A и вложенную синхронизированную операцию на объекте B, а поток T2 выполняет синхронизированную операцию на объекте B и вложенную синхронизированную операцию на объекте A, мы получаем другую форму взаимоблокировки.



Поток T1 может получить монитор объекта A одновременно с тем, что поток T2 получит монитор объекта B, а затем каждый поток будет ожидать монитора В и А соответственно неопределенный срок.

Одним из лучших способов предотвращения взаимоблокировки — это избегать одновременного получения более одного монитора.

Еще одно нарушение живучести, это LIVELOCK или динамическая взаимоблокировка.

В livelock потоки не блокируются, но они находятся в режиме, в котором их выполнение не продвигается дальше, это похоже на пат в шахматной игре.



Например, если у нас есть объект, скажем, изменяемая целочисленная переменная x, и у нас есть два потока.

Поток T1 в цикле увеличивает x, затем читает значение x и продолжает делать это, пока х меньше 2.

А поток T2 в цикле уменьшает значение x, затем читает значение x и продолжает делать это, пока х больше -2.

Возможна ситуация, при которой поток T1 получает x = 1, но прежде чем он получит шанс увеличить x и достичь x = 2, поток T2 уменьшает x, противодействуя тому, что делает T1.

И делает x = -1.

Но до того, как поток T2 получит шанс уменьшить х до -2, поток T1 может снова увеличить x до 1.

И так до бесконечности.

Таким образом, значение х может двигаться вперед и назад, как непрерывный бесконечный пинг-понг.

Теперь третий вид проблемы с живучестью, называется STARVATION или голодание.

Starvation возникает, когда какой-либо поток не может получить доступ к общим ресурсам и не может быть выполнен в результате, например, синхронизированного доступа к этому ресурсу другими потоками, выполнение которых занимает долгое время.



В результате этот поток голодает.

Паттерн защищенный блок Guarded Block



Перейти на страницу:

Похожие книги

«Ага!» и его секреты
«Ага!» и его секреты

Вы бы не хотели, скажем, изобрести что-то или открыть новый физический закон, а то и сочинить поэму или написать концерт для фортепьяно с оркестром?Не плохо бы, верно? Только как это сделать? Говорят, Шиллер уверял, будто сочинять стихи ему помогает запах гнилых яблок. И потому, принимаясь за работу, всегда клал их в ящик письменного стола. А физик Гельмгольц поступал иначе. Разложив все мысленно по полочкам, он дожидался вечера и медленно поднимался на гору лесной дорогой. Во время такой прогулки приходило нужное решение.Словом, сколько умов, столько способов заставить мозг работать творчески. А нет ли каких-то строго научных правил? Одинаковы ли они для математиков, биологов, инженеров, поэтов, художников? Да и существуют ли такие приемы, или каждый должен полагаться на свои природные способности и капризы вдохновения?Это тем более важно знать, что теперь появились «электронные ньютоны» — машины, специальность которых делать открытия. Но их еще нужно учить.Решающее слово здесь принадлежит биологам: именно они должны давать рецепты инженерам. А биологи и сами знают о том, как мы думаем, далеко не все. Им предстоит еще активнее исследовать лабораторию нашего мышления.О том, как ведутся эти исследования, как постепенно «умнеют» машины, как они учатся и как их учат, — словом, о новой науке эвристике рассказывает эта книга.

Елена Викторовна Сапарина

Зарубежная компьютерная, околокомпьютерная литература
Создание трилогии BioShock. От Восторга до Колумбии
Создание трилогии BioShock. От Восторга до Колумбии

Всего за три игры сага BioShock заняла особое место в сердцах игроков. Она может похвастаться проработанными и совершенно уникальными персонажами и мирами. Действие первых двух частей происходит в подводном городе Восторг, где игрок погружается в стиль ар-деко и атмосферу 1950-х годов. Третья часть, BioShock Infinite, переносит вас в 1912 год и приглашает исследовать небесный город Колумбия в сеттинге стимпанка.В книге вас ждут:[ul]рассуждение об источниках вдохновения создателя серии Кена Левина;исследование уникального геймплея и механик;подробности разработки игр франшизы от идеи до выпуска;глубокий анализ сюжета, тем и персонажей каждой части.[/ul]Авторы отдают дань уважения популярной серии игр, которая, несмотря на короткую историю, уже получила признание критиков.В формате PDF A4 сохранен издательский макет книги.

Мехди Эль Канафи , Николя Курсье , Рафаэль Люка

Зарубежная компьютерная, околокомпьютерная литература