Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Общие вопросы > Идеология методов wait, notify, notifyAll. |
Автор: Bakuard 1.10.2017, 12:50 |
Доброго времени суток. Возникло несколько вопросов связанных с поведением методов wait, notify, notifyAll. Сразу хочу уточнить - я понимаю как работают эти методы, но не понимаю, почему разработчики языка решили реализовать именно такое поведение. А именно: Почему для вызовов этих методов необходимо владеть монитором объекта? Почему эти методы реализованы в классе Object? Помогите пожалуйста разобраться. |
Автор: rfq 15.12.2017, 02:11 |
Параллельное программирование - это очень просто, запускай себе потоки и процессы, делов-то. Сложности начинаются, когда параллельные процессы должны взаимодействовать. Рассмотрим простейший пример: - поток А записывает значение в переменную П - поток Б читает это значение Поскольку про относительную скорость потоков нам ничего не известно, то как избежать ситуации, когда Б будет читать еще не записанное значение? Решение в том, чтобы для обмена данными использовать не простые переменные, а контейнеры токенов. Токен (token) - это фишка в настольной игре. Его можно разместить на клетке игрового поля, можно передвинуть, при этом из прежней клетки он исчезает. Фишки казино - тоже токены, они перемещаются от дилера к игроку и обратно. Конкретно в нашем случае, поток А кладет токен в контейнер К, а поток Б пытается его извлечь. При этом если токена там еще нет, поток засыпает до момента его появления. Операция размещения токенов будит ждущие потоки, если они есть. Собственно, токен - это обычное значение, примитивного или ссылочного типа, токеном его делает контейнер, в котором он размещается. Контейнер - это объект, обеспечивающий надежную реализацию операций размещения и извлечения токенов в многопоточной среде. Итак, для организации контейнера токенов нам надо 3 вещи: - блокировка контейнера на время операции - как правило, нам нужно несколько действий, чтобы разместить или извлечь токен, важно, чтобы никто во время операции не вклинивался, не только с записью, но и с чтением - операция перехода потока в состояние ожидания события изменения состояния контейнера (поток может ждать не только размещения токена, но и освобождения места, чтобы положить свой токен) - операция оповещения ждущих потоков о том, что состояние контейнера изменилось. Вы, конечно, узнали операции synchronized, wait и notify. Ну а почему эти операции разработчики языка решили сделать применимыми к любому объекту - просто поняли, что так сделать можно и решили не ограничивать свободу программиста, чтобы он мог сделать контейнер на базе любого существующего класса. Вот только я считаю, что начинать изучение параллельного программирования с написания контейнеров токенов (иными словами, с использования вышеупомянутых операций) - это неправильно. Это ответственное дело, полное подводных камней, требующее высокой квалификации. Существуют готовые реализации контейнеров, например, реализации интерфейса BlockingQueue, которые закроют ваши потребности на 90%, еще несколько процентов закроет класс Semaphore - контейнер для неразличимых токенов. Свои контейнеры нужны, если у вас возникли специфические задачи, а вы уже перепробовали все стандартные реализации и остались неудовлетворенными. И конечно, прежде чем начать писать свое, нужно изучить коды стандартных реализаций. |