VB.Net Tutorial/Thread/Producer and consumer

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

Producer and consumer

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
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

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
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

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
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

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
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.