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

Еще одно нарушение живучести, это 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



Предположим у нас есть задача написать приложение Producer-Consumer.

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

Купите полную версию книги и продолжайте чтение
Купить полную книгу