Иллюстрированный самоучитель по VB.NET




Совместная работа с данными по мере их создания - часть 3


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

23 Public Property TheWeek() As Integer

24 Get

25 Return mweek

26 End Get

27 Set(ByVal Value As Integer)

28 mweek - Value

29 End Set

30 End Property

31 Public Property OurMoney() As Integer

32 Get

33 Return mMoney

34 End Get

35 Set(ByVal Value As Integer)

36 mMoney =Value

37 End Set

38 End Property

39 Public Sub Produce()

40 Thread.Sleep(500)

41 Do

42 Monitor.Enter(Me)

43 Do While Me.OurMoney > 0

44 Monitor.Wait(Me)

45 Loop

46 Me.OurMoney =1000

47 Monitor.PulseAll(Me)

48 Monitor.Exit(Me)

49 Loop

50 End Sub

51 Public Sub Consume()

52 MsgBox("Am in consume thread")

53 Do

54 Monitor.Enter(Me)

55 Do While Me.OurMoney = 0

56 Monitor.Wait(Me)

57 Loop

58 Console.WriteLine("Dear parent I just spent all your " & _

money in week " & TheWeek)

59 TheWeek += 1

60 If TheWeek = 21 *52 Then System.Environment.Exit(0)

61 Me.OurMoney =0

62 Monitor.PulseAll(Me)

63 Monitor.Exit(Me)

64 Loop

65 End Sub

66 End Class

Метод StartltsLife (строки 13-22) осуществляет подготовку к запуску потоков Produce и Consume. Самое главное происходит в потоках Produce (строки 39-50) и Consume (строки 51-65). Процедура Sub Produce проверяет наличие денег, и если деньги есть, переходит в очередь ожидания. В противном случае родитель генерирует деньги (строка 46) и оповещает объекты в очереди ожидания об изменении ситуации. Учтите, что вызов Pulse-Pulse All вступает в силу лишь при снятии блокировки командой Monitor.Exit. И наоборот, процедура Sub Consume проверяет наличие денег, и если денег нет — оповещает об этом ожидающего родителя. Строка 60 просто завершает программу по прошествии 21 условного года; вызов System.Environment.Exit(0) является .NET-аналогом команды End (команда End тоже поддерживается, но в отличие от System. Environment. Exit она не позволяет вернуть код завершения операционной системе).

Потоки, переведенные в очередь ожидания, должны быть освобождены другими час-тями вашей программы. Именно по этой причине мы предпочитаем использовать PulseAll вместо Pulse. Поскольку заранее неизвестно, какой именно поток будет активизирован при вызове Pulse 1 , при относительно небольшом количестве потоков в очереди с таким же успехом можно вызвать PulseAll.




Содержание  Назад  Вперед