VB.Net Tutorial/Thread/Producer and consumer — различия между версиями

Материал из VB Эксперт
Перейти к: навигация, поиск
м (1 версия)
 
(нет различий)

Текущая версия на 15:56, 26 мая 2010

Producer and consumer

<source lang="vbnet">Imports System.Threading Module Module1

   Public Buffer As Integer
   Public BufferEmpty As Boolean = True
   Sub Producer()
       Dim Value As Integer = 0
       Do
           If (BufferEmpty) Then
               BufferEmpty = False
               Buffer = Value
               If (Value = 0) Then
                   Value = 1
               Else
                   Value = 0
               End If
               Console.WriteLine("Producer: " & Buffer)
           End If
       Loop While (True)
   End Sub
   Sub Consumer()
       Dim Value As Integer
       Do
           If (Not BufferEmpty) Then
               BufferEmpty = True
               Thread.CurrentThread.Sleep(1000)
               Value = Buffer
               Console.WriteLine("Consumer: " & Value)
           End If
       Loop While (True)
   End Sub
   Sub Main()
       Dim ProducerThread As Thread
       Dim ConsumerThread As Thread
       ProducerThread = New Thread(AddressOf Producer)
       ConsumerThread = New Thread(AddressOf Consumer)
       ProducerThread.Start()
       ConsumerThread.Start()
   End Sub

End Module</source>

Producer: 0
Producer: 1
Consumer: 1
Producer: 0
Consumer: 0
Producer: 1
Consumer: 1
Producer: 0
Consumer: 0
Producer: 1
^CTerminate batch job (Y/N)? n

Producer and consumer without synchronization mechanisms

<source lang="vbnet">Imports System.Threading Module Tester

  Sub Main()
     Dim holdInteger As New Buffer()
     Dim producer As New Producer(holdInteger)
     Dim consumer As New Consumer(holdInteger)
     Dim producerThread As New Thread(AddressOf producer.Produce)
     Dim consumerThread As New Thread(AddressOf consumer.Consume)
     producerThread.Name = "Producer"
     consumerThread.Name = "Consumer"
     producerThread.Start()
     consumerThread.Start()
  End Sub

End Module Public Class Producer

  Private buffer As Buffer
  Public Sub New(ByVal sharedObject As Buffer)
     buffer = sharedObject
  End Sub " New
  Public Sub Produce()
     Dim count As Integer
     For count = 1 To 4
        Thread.Sleep(4000)
        buffer.Buffer = count
     Next
     Console.WriteLine(Thread.CurrentThread.Name & _
        " done producing." & vbCrLf & "Terminating " & _
        Thread.CurrentThread.Name & ".")
  End Sub 

End Class Public Class Consumer

  Private buffer As Buffer
  Public Sub New(ByVal sharedObject As Buffer)
     buffer = sharedObject
  End Sub " New
  Public Sub Consume()
     Dim count, sum As Integer
     For count = 1 To 4
        Thread.Sleep(300)
        sum += buffer.Buffer
     Next
     Console.WriteLine(Thread.CurrentThread.Name & _
        " read values totaling: " & sum & "." & vbCrLf & _
        "Terminating " & Thread.CurrentThread.Name & ".")
  End Sub 

End Class

Public Class Buffer

  Private mBuffer As Integer = -1
  Property Buffer() As Integer
     Get
        Console.WriteLine(Thread.CurrentThread.Name & _
           " reads " & mBuffer)
        Return mBuffer
     End Get
     Set(ByVal Value As Integer)
        Console.WriteLine(Thread.CurrentThread.Name & _
           " writes " & Value)
        mBuffer = Value
     End Set
  End Property " Buffer

End Class</source>

Consumer reads -1
Consumer reads -1
Consumer reads -1
Consumer reads -1
Consumer read values totaling: -4.
Terminating Consumer.
Producer writes 1
Producer writes 2
Producer writes 3
^CTerminate batch job (Y/N)? ^Cn

Producer and consumer with synchronization mechanisms

<source lang="vbnet">Imports System.Threading Module Tester

  Sub Main()
     Dim holdInteger As New Buffer()
     Dim producer As New Producer(holdInteger)
     Dim consumer As New Consumer(holdInteger)
     Dim producerThread As New Thread(AddressOf producer.Produce)
     Dim consumerThread As New Thread(AddressOf consumer.Consume)
     producerThread.Name = "Producer"
     consumerThread.Name = "Consumer"
     producerThread.Start()
     consumerThread.Start()
  End Sub

End Module Public Class Producer

  Private buffer As Buffer
  Public Sub New(ByVal sharedObject As Buffer)
     buffer = sharedObject
  End Sub " New
  Public Sub Produce()
     Dim count As Integer
     For count = 1 To 4
        Thread.Sleep(4000)
        buffer.Buffer = count
     Next
     Console.WriteLine(Thread.CurrentThread.Name & _
        " done producing." & vbCrLf & "Terminating " & _
        Thread.CurrentThread.Name & ".")
  End Sub 

End Class Public Class Consumer

  Private buffer As Buffer
  Public Sub New(ByVal sharedObject As Buffer)
     buffer = sharedObject
  End Sub " New
  Public Sub Consume()
     Dim count, sum As Integer
     For count = 1 To 4
        Thread.Sleep(300)
        sum += buffer.Buffer
     Next
     Console.WriteLine(Thread.CurrentThread.Name & _
        " read values totaling: " & sum & "." & vbCrLf & _
        "Terminating " & Thread.CurrentThread.Name & ".")
  End Sub 

End Class Public Class Buffer

  Private mBuffer As Integer = -1
  Private occupiedBufferCount As Integer
  Public Property Buffer() As Integer
     Get
        Monitor.Enter(Me)
        If occupiedBufferCount = 0 Then
           Console.WriteLine("Buffer empty. " & _
              Thread.CurrentThread.Name & " waits.")
           Monitor.Wait(Me)
        End If
        occupiedBufferCount -= 1
        Console.WriteLine(Thread.CurrentThread.Name & " reads " & _
           mBuffer)
        Monitor.Pulse(Me)
        Dim bufferCopy As Integer = mBuffer
        Monitor.Exit(Me)
        Return bufferCopy
     End Get
     Set(ByVal Value As Integer)
        Monitor.Enter(Me)
        If occupiedBufferCount = 1 Then
           Console.WriteLine("Buffer full. " & _
              Thread.CurrentThread.Name & " waits.")
           Monitor.Wait(Me)
        End If
        mBuffer = Value
        occupiedBufferCount += 1
        Console.WriteLine(Thread.CurrentThread.Name & " writes " & _
           mBuffer)
        Monitor.Pulse(Me)
        Monitor.Exit(Me)
     End Set
  End Property " Buffer

End Class</source>

Buffer empty. Consumer waits.
Producer writes 1
Consumer reads 1
Buffer empty. Consumer waits.
Producer writes 2
Consumer reads 2
Buffer empty. Consumer waits.
Producer writes 3
Consumer reads 3
Buffer empty. Consumer waits.
Producer writes 4
Consumer reads 4
Consumer read values totaling: 10.
Terminating Consumer.
Producer done producing.
Terminating Producer.

Synchronize access to circular Integer buffer

<source lang="vbnet">Imports System.Threading Public Class Tester

  Public Shared Sub Main
     Dim buffer As New Buffer()
     Dim producer As New Producer(buffer)
     Dim consumer As New Consumer(buffer)
     Dim producerThread As New Thread(AddressOf producer.Produce)
     Dim consumerThread As New Thread(AddressOf consumer.Consume)
     producerThread.Name = "Producer"
     consumerThread.Name = "Consumer"
     producerThread.Start()
     consumerThread.Start()
  End Sub 

End Class

Public Class Buffer

  Private mBuffer As Integer() = {-1, -1, -1}
  Private occupiedBufferCount As Integer
  Private readlocation, writeLocation As Integer
  Property Buffer() As Integer
     Get
        SyncLock (Me)
           If occupiedBufferCount = 0 Then
              Console.WriteLine("All buffers empty. " & _
                 Thread.CurrentThread.Name & " waits.")
              Monitor.Wait(Me)
           End If
           Dim readValue As Integer = mBuffer(readlocation)
           Console.WriteLine(Thread.CurrentThread.Name & " reads " & _
              mBuffer(readlocation))
           occupiedBufferCount -= 1
           readlocation = (readlocation + 1) Mod mBuffer.Length
           Monitor.Pulse(Me)
           Return readValue
        End SyncLock
     End Get
     Set(ByVal Value As Integer)
        SyncLock (Me)
           If occupiedBufferCount = mBuffer.Length Then
              Console.WriteLine("All buffers full. " & _
                 Thread.CurrentThread.Name & " waits.")
              Monitor.Wait(Me)
           End If
           mBuffer(writeLocation) = Value
           Console.WriteLine(Thread.CurrentThread.Name & " writes " & _
              mBuffer(writeLocation) )
           occupiedBufferCount += 1
           writeLocation = (writeLocation + 1) Mod _
              mBuffer.Length
           Monitor.Pulse(Me)
        End SyncLock
     End Set
  End Property " Buffer

End Class

Public Class Producer

  Private buffer As Buffer
  Public Sub New(ByVal sharedObject As Buffer)
     buffer = sharedObject
  End Sub 
  Public Sub Produce()
     Dim count As Integer
     For count = 1 To 10
        Thread.Sleep(1000)
        buffer.Buffer = count
     Next
     Console.WriteLine(Thread.CurrentThread.Name & _
        " done producing. " & vbCrLf & _
        Thread.CurrentThread.Name & " terminated.")
  End Sub 

End Class Public Class Consumer

  Private buffer As Buffer
  Public Sub New(ByVal sharedObject As Buffer)
     buffer = sharedObject
  End Sub 
  Public Sub Consume()
     Dim count, sum As Integer
     For count = 1 To 10
        Thread.Sleep(500)
        sum += buffer.Buffer
     Next
     Console.WriteLine("Total " & _
        Thread.CurrentThread.Name & " consumed: " & sum & vbCrLf & _
        Thread.CurrentThread.Name & " terminated.")
  End Sub

End Class</source>

All buffers empty. Consumer waits.
Producer writes 1
Consumer reads 1
All buffers empty. Consumer waits.
Producer writes 2
Consumer reads 2
All buffers empty. Consumer waits.
Producer writes 3
Consumer reads 3
All buffers empty. Consumer waits.
Producer writes 4
Consumer reads 4
All buffers empty. Consumer waits.
Producer writes 5
Consumer reads 5
All buffers empty. Consumer waits.
Producer writes 6
Consumer reads 6
All buffers empty. Consumer waits.
Producer writes 7
Consumer reads 7
All buffers empty. Consumer waits.
Producer writes 8
Consumer reads 8
All buffers empty. Consumer waits.
Producer writes 9
Consumer reads 9
All buffers empty. Consumer waits.
Producer writes 10
Producer done producing.
Producer terminated.
Consumer reads 10
Total Consumer consumed: 55
Consumer terminated.