Если вы не получите повторно блокирующий объект, как потоки узнают, что они закончили ожидание? Что скажет им это? Возвращение из блока им ничего не говорит, потому что блокирующий объект не имеет состояния. У него нет состояния «разблокировано» или «не блокировано», чтобы он мог вернуться в него.
Вы должны передать им некоторые данные, иначе как они узнают об этом раньше, чем им пришлось ждать, а теперь нет? Переменная условия не содержит состояний, поэтому любое необходимое вам состояние должно поддерживаться и передаваться вами.
Одним из распространенных шаблонов является использование мьютекса, переменной условия и целого числа состояния. Чтобы заблокировать, сделайте это:
Получить мьютекс.
Скопировать значение целого числа состояния.
Блокировать переменную условия, освобождая мьютекс.
Если целое число состояния такое же, как и при копировании, перейдите к шагу 3.
Отключить мьютекс.
Чтобы разблокировать все темы, сделайте следующее:
Получить мьютекс.
Увеличение целого числа состояния.
Трансляция переменной условия.
Отключить мьютекс.
Обратите внимание, как шаг 4 алгоритма блокировки проверяет, завершен ли поток ожидания? Обратите внимание, как этот код отслеживает, была ли разблокировка с тех пор, как поток решил заблокировать? Вы должны сделать это, потому что переменные условия не делают это сами. (И именно поэтому вам нужно повторно захватить объект блокировки.)
Если вы попытаетесь удалить целочисленное состояние, ваш код будет работать непредсказуемо. Иногда вы будете блокировать слишком долго из-за пропущенных пробуждений, а иногда вы не будете блокировать достаточно долго из-за ложных пробуждений. Только целое состояние (или аналогичный предикат), защищенный мьютексом, сообщает потокам, когда ждать, а когда прекратить ожидание.
Кроме того, я не видел, как ваш код использует это, но он почти всегда превращается в логику, которую вы уже используете. Почему потоки блокируются в любом случае? Это потому, что у них нет работы? И когда они проснутся, они поймут, что делать? Что ж, для выяснения того, что для них нет работы, а для выяснения того, что им нужно делать, потребуется некоторая блокировка, поскольку это общее состояние, верно? Таким образом, почти всегда есть блокировка, которую вы держите, когда решаете заблокировать, и вам нужно повторно получить ее, когда вы закончите ждать.