Page 251 - 6253
P. 251
час володіти монітором. Коли потік робить запит на блокування, то кажуть, що він
входить в монітор. Всі інші потоки, які намагаються увійти в заблокований монітор,
будуть призупинені до того часу, поки потік, що отримав блокування не покине з
монітор. Про всі інші потоки говорять, що вони очікують монітора. Потік, який
володіє монітором, за необхідності може повторно в нього увійти.
У термінології мови Java монітор володіє наступними властивостями:
1. Монітор – це клас, що має тільки закриті поля.
2. У кожного об’єкта такого класу є зв’язане з ним блокування.
3. Всі методи блокуються даним блокуванням. Тобто, якщо клієнт викликає
метод obj.method(), блокування об’єкта obj автоматично захоплюється під час
виклику цього методу і знімається під час його завершення. А оскільки всі поля
класу монітора закриті, то такий підхід гарантує, що до них не можна буде
звернутися із жодного потоку доти, поки ними маніпулює будь-який інший потік.
4. Блокування може мати будь-яку кількість пов’язаних з ним умов.
Розробники мови Java вільно адаптували принцип монітора. Кожен об’єкт в
Java володіє вбудованим блокуванням і вбудованою умовою. Якщо метод
оголошений із ключовим словом synchronized, то він діє як метод монітора. Умовна
змінна доступна через виклики методів wait(), notifyAll() та notify(). Проте, об’єкти в
мові Java відрізняються від класичної реалізації монітора наступними трьома
важливими пунктами, що потенційно можуть впливати на безпеку потоків:
1. Поля не обов’язково повинні бути закритими (private).
2. Методи не зобов’язані бути синхронізованими (synchronized).
3. Клієнтам доступне керування вбудованим блокуванням.
Ці пункти свідчать про явне нехтування вимогами безпеки, викладеними Пером
Брінчем Хансеном (Fer Brinch Hansen) і Тоні Хоаром (Тоnу Ноаrе) в 1970-х роках.
Щоб уникнути пошкодження даних, що спільно використовуються декількома
потоками, необхідно синхронізувати доступ до них із різних потоків. У наступному
прикладі програми імітується робота банку з декількома рахунками. Згенеруємо
випадковим чином декілька транзакції, що переводять гроші з одного рахунку на
інший. Кожна транзакція переміщає довільну суму грошей з рахунку, що
обслуговується поточним потоком, на іншій довільно обираний рахунок.
250