Разница между Monitor.Pulse и Monitor.PulseAll
Monitor.PulseAll
уведомляет все ожидающие потоки в очереди.
Monitor.Pulse
уведомляет поток в очереди ожидания. (Следующий ожидающий поток)
Только следующий поток (один поток) может получить блокировку. Так в чем же разница?
Когда мне следует использовать Pulse
vs PulseAll
?
Ответы
Ответ 1
Используйте PulseAll
, когда вы хотите пробудить несколько потоков, потому что условие, которое они ожидают, теперь может выполняться для нескольких потоков. (Ожидание почти всегда связано с условием - вы обычно должны тестировать это условие в цикле while
.)
Используйте Pulse
, когда вы хотите только пробудить один поток, потому что только один поток действительно сможет выполнять полезную работу.
Чтобы дать две аналогию:
Представьте, что у вас есть один принтер. Только один человек может использовать его за раз, поэтому, если у вас много ожидающих людей, вы отправляете их всех спать - но вы только разбудите одного человека, когда принтер станет свободным. Это отражает использование Pulse
.
Теперь представьте, что вы запустили магазин. Пока вы закрыты, клиенты ждут возле магазина. Когда вы открываете магазин, вы не просто хотите разбудить одного клиента - они все могут войти. Это отражает использование PulseAll
.
Ответ 2
A Monitor
имеет две очереди: очередь ожидания и готовую очередь. В отсутствие Wait
и Pulse
все потоки, которые пытаются получить блокировку, попадают в готовую очередь. Когда блокировка станет доступной, один поток из готовой очереди получит ее.
Когда поток получает блокировку и затем выполняет Wait
, этот поток переходит в очередь ожидания. Он ждет Pulse
или PulseAll
и останется в очереди ожидания, пока не получит Pulse
, даже если другие потоки из очереди готовности приобретут и освободят блокировку.
Pulse
перемещает один поток из очереди ожидания в готовую очередь. PulseAll
перемещает ВСЕ потоки из очереди ожидания в готовую очередь.
Ключевым моментом здесь является то, что потоки в очереди ожидания никогда не смогут получить блокировку. Они ждут, когда импульс переместит их обратно в готовую очередь, чтобы они могли получить блокировку, когда она станет доступной.
Там достаточно хорошее обсуждение Wait and Pulse - по крайней мере, немного, чтобы вы начали... здесь.