Текст книги "Многопоточное программирование в Java"
![](/books_files/covers/thumbs_240/mnogopotochnoe-programmirovanie-vjava-296734.jpg)
Автор книги: Тимур Машнин
Жанр: Компьютеры: прочее, Компьютеры
Возрастные ограничения: +12
сообщить о неприемлемом содержимом
Текущая страница: 2 (всего у книги 2 страниц)
Живучесть Liveness
![](image23_60091c4883141305b1e7c572_jpg.jpeg)
Теперь, давайте рассмотрим фундаментальное свойство корректности многопоточных программ, которое называется LIVENESS или живучесть.
Когда вы пишете не многопоточную, а последовательную программу, и в ней есть ошибка, вы запускаете ее, и на экране ничего не появляется.
Вы ждете, а затем выясняете, например, что у вас в коде есть бесконечный цикл.
И тогда вы исправляете ошибку.
К сожалению, в многопоточных программах есть много других способов получить этот эффект пустого экрана.
Один из них – это DEADLOCK или взаимная блокировка.
Это мы уже видели в случае операции join.
![](image24_60091c4683141305b1e7c56f_jpg.jpeg)
Если два потока соединяются друг с другом, они создают цикл взаимоблокировки, и по этой причине программа не завершается.
Это не бесконечный цикл в обычном понимании, это два потока, заблокированных друг от друга на неопределенный срок.
Существуют и другие способы получения взаимоблокировки.
Например, если поток T1 выполняет синхронизированную операцию на объекте A и вложенную синхронизированную операцию на объекте B, а поток T2 выполняет синхронизированную операцию на объекте B и вложенную синхронизированную операцию на объекте A, мы получаем другую форму взаимоблокировки.
![](image25_60091c4483141305b1e7c56c_jpg.jpeg)
Поток T1 может получить монитор объекта A одновременно с тем, что поток T2 получит монитор объекта B, а затем каждый поток будет ожидать монитора В и А соответственно неопределенный срок.
Одним из лучших способов предотвращения взаимоблокировки – это избегать одновременного получения более одного монитора.
Еще одно нарушение живучести, это LIVELOCK или динамическая взаимоблокировка.
В livelock потоки не блокируются, но они находятся в режиме, в котором их выполнение не продвигается дальше, это похоже на пат в шахматной игре.
![](image26_60091c4183141305b1e7c569_jpg.jpeg)
Например, если у нас есть объект, скажем, изменяемая целочисленная переменная 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 возникает, когда какой-либо поток не может получить доступ к общим ресурсам и не может быть выполнен в результате, например, синхронизированного доступа к этому ресурсу другими потоками, выполнение которых занимает долгое время.
![](image27_60091c3f83141305b1e7c566_jpg.jpeg)
В результате этот поток голодает.
Паттерн защищенный блок Guarded Block
![](image28_60091c3d83141305b1e7c563_jpg.jpeg)
Предположим у нас есть задача написать приложение Producer-Consumer.
Это приложение состоит из двух потоков – производителя, который создает данные, и потребителя, который что-то делает с этими данными.
Внимание! Это не конец книги.
Если начало книги вам понравилось, то полную версию можно приобрести у нашего партнёра - распространителя легального контента. Поддержите автора!Правообладателям!
Данное произведение размещено по согласованию с ООО "ЛитРес" (20% исходного текста). Если размещение книги нарушает чьи-либо права, то сообщите об этом.Читателям!
Оплатили, но не знаете что делать дальше?