Cамоучитель по VB.NET

       

Проблемы многопоточности




В процедуре Sub Main (строки 4-7) создается «дом» с десятью «комнатами». Класс House устанавливает максимальную температуру 75 градусов по Фаренгейту (около 24 градусов по Цельсию). В строках 13-28 определяется довольно сложный конструктор дома. Ключевыми для понимания программы являются строки 18-27. Строка 20 создает очередной объект комнаты, при этом конструктору передается ссылка на объект дома, чтобы объект комнаты при необходимости мог к нему обратиться. Строки 21-23 запускают десять потоков для регулировки температуры в каждой комнате. Класс Room определяется в строках 38-73. Ссылка на объект House coxpaняется в переменной mHouse в конструкторе класса Room (строка 43). Код проверки и регулировки температуры (строки 50-66) выглядит просто и естественно, но как вы вскоре убедитесь, это впечатление обманчиво! Обратите внимание на то, что этот код заключен в блок Try-Catch, поскольку в программе используется метод Sleep.

Вряд ли кто-нибудь согласится жить при температуре в 105 градусов по Фаренгейту (40,5 24 градусов по Цельсию). Что же произошло? Проблема связана со следующей строкой:

If mHouse.HouseTemp < mHouse.MAX_TEMP - 5 Then

А происходит следующее: сначала температуру проверяет поток 1. Он видит, что температура слишком низка, и поднимает ее на 5 градусов. К сожалению, перед повышением температуры поток 1 прерывается и управление передаётся поток 2. Поток 2 проверяет ту же самую переменную, которая еще не была изменена потоком 1. Таким образом, поток 2 тоже готовится поднять температуру на 5 градусов, но сделать этого не успевает и тоже переходит в состояние ожидания. Процесс продолжается до тех пор, пока поток 1 не активизируется и не перейдет к следующей команде — повышению температуры на 5 градусов. Повышение повторяется при активизации всех 10 потоков, и жильцам дома придется плохо.





Содержание раздела