Совместная работа с данными по мере их создания
На псевдокоде идиома потребителя данных формулируется так:
' Вход в синхронизированный блок следующего вида While нет данных Перейти в очередь ожидания Loop Если данные есть, обработать их. Покинуть синхронизированный блок
Сразу же после выполнения команды Wait поток приостанавливается, блокировка снимается, и поток переходит в очередь ожидания. При снятии блокировки поток, находящийся в очереди выполнения, получает возможность работать. Со временем один или несколько заблокированных потоков создадут данные, необходимые для работы потока, находящегося в очереди ожидания. Поскольку проверка данных осуществляется в цикле, переход к использованию данных (после цикла) происходит лишь при наличии данных, готовых к обработке.
На псевдокоде идиома поставщика данных выглядит так:
' Вход в синхронизированный блок вида While данные НЕ нужны Перейти в очередь ожидания Else Произвести данные После появления готовых данных вызвать Pulse-PulseAll, 'чтобы переместить один или несколько потоков из очереди блокировки в очередь выполнения. Покинуть синхронизированный блок (и вернуться в очередь выполнения)
Предположим, наша программа моделирует семью с одним родителем, который зарабатывает деньги, и ребенком, который эти деньги тратит. Когда деньги кончаются, ребенку приходится ждать прихода новой суммы. Программная реализация этой модели выглядит так:
1 Option Strict On 2 Imports System.Threading 3 Module Modulel 4 Sub Main() 5 Dim theFamily As New Family() 6 theFamily.StartltsLife() 7 End Sub 8 End fjodule 9 10 Public Class Family 11 Private mMoney As Integer 12 Private mWeek As Integer = 1 13 Public Sub StartltsLife() 14 Dim aThreadStart As New ThreadStarUAddressOf Me.Produce) 15 Dim bThreadStart As New ThreadStarUAddressOf Me.Consume) 16 Dim aThread As New Thread(aThreadStart) 17 Dim bThread As New Thread(bThreadStart) 18 aThread.Name = "Produce" 19 aThread.Start() 20 bThread.Name = "Consume" 21 bThread. Start() 22 End Sub