VB.Net/Thread/Producer Consumer

Материал из VB Эксперт
Версия от 15:45, 26 мая 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Producer and Consumer with Synchronized Integer Buffer

<source lang="vbnet"> " ************************************************************* " * (C) Copyright 2003 by Deitel & Associates, Inc. * " * and Prentice Hall. * " * All Rights Reserved. * " * * " * DISCLAIMER: The authors and publisher of this book have * " * used their best efforts in preparing the book. These * " * efforts include the development, research, and testing of * " * the theories and programs to determine their * " * effectiveness. The authors and publisher make no warranty * " * of any kind, expressed or implied, with regard to these * " * programs or to the documentation contained in these books.* " * The authors and publisher shall not be liable in any event* " * for incidental or consequential damages in connection * " * with, or arising out of, the furnishing, performance, or * " * use of these programs. * " *************************************************************

Imports System Imports System.Threading Public Class MainClass

  Shared Sub Main()
     " create shared object used by threads
     Dim holdInteger As New SynchronizedIntegerBuffer()
     " Random object used by each thread
     Dim randomObject As New Random()
     " create Producer and Consumer objects
     Dim producer As New CProducer(holdInteger, randomObject)
     Dim consumer As New CConsumer(holdInteger, randomObject)
     " create threads for producer and consumer  
     " set delegates for each thread
     Dim producerThread As New Thread(AddressOf producer.Produce)
     Dim consumerThread As New Thread(AddressOf consumer.Consume)
     " name each thread
     producerThread.Name = "Producer"
     consumerThread.Name = "Consumer"
     " start each thread
     producerThread.Start()
     consumerThread.Start()
  End Sub " Main

End Class " Produces integers from 1 to 4 and places them in unsynchronized buffer. Public Class CProducer

  Private sharedLocation As SynchronizedIntegerBuffer
  Private randomSleepTime As Random
  Public Sub New(ByVal sharedObject As _
     SynchronizedIntegerBuffer, ByVal randomObject As Random)
     sharedLocation = sharedObject
     randomSleepTime = randomObject
  End Sub
  Public Sub Produce()
     Dim count As Integer
     For count = 1 To 4
        Thread.Sleep(randomSleepTime.Next(3000))
        sharedLocation.Buffer = count
     Next
     Console.WriteLine(Thread.CurrentThread.Name & _
        " done producing." & vbCrLf & "Terminating " & _
        Thread.CurrentThread.Name & ".")
  End Sub

End Class " Consumes 4 integers from unsynchronized buffer. Public Class CConsumer

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

End Class " Synchronizes access to an Integer. Public Class SynchronizedIntegerBuffer

  Private mBuffer As Integer = -1
  Private occupiedBufferCount As Integer
  Public Property Buffer() As Integer
     Get
        " obtain lock on this object
        Monitor.Enter(Me)
        If occupiedBufferCount = 0 Then
           Console.WriteLine(Thread.CurrentThread.Name & _
              " tries to read.")
           DisplayState("Buffer empty. " & _
              Thread.CurrentThread.Name & " waits.")
           Monitor.Wait(Me)
        End If
        occupiedBufferCount -= 1
        DisplayState(Thread.CurrentThread.Name & " reads " & _
           mBuffer)
        Monitor.Pulse(Me)
        " Get copy of buffer before releasing lock.
        " It is possible that the producer could be
        " assigned the processor immediately after the 
        " monitor is released and before the return
        " statement executes. In this case, the producer
        " would assign a new value to buffer before the
        " return statement returns the value to the 
        " consumer. Thus, the consumer would receive the
        " new value. Making a copy of buffer and 
        " returning the copy helps ensure that the
        " consumer receives the proper value.
        Dim bufferCopy As Integer = mBuffer
        " release lock on this object
        Monitor.Exit(Me)
        Return bufferCopy
     End Get
     Set(ByVal Value As Integer)
        " acquire lock for this object
        Monitor.Enter(Me)
        " if there are no empty locations, place invoking
        " thread in WaitSleepJoin state
        If occupiedBufferCount = 1 Then
           Console.WriteLine(Thread.CurrentThread.Name & _
              " tries to write.")
           DisplayState("Buffer full. " & _
              Thread.CurrentThread.Name & " waits.")
           Monitor.Wait(Me)
        End If
        " set new buffer value
        mBuffer = Value
        occupiedBufferCount += 1
        DisplayState(Thread.CurrentThread.Name & " writes " & _
           mBuffer)
        Monitor.Pulse(Me)
        Monitor.Exit(Me)
     End Set
  End Property
  Public Sub DisplayState(ByVal operation As String)
     Console.WriteLine("{0,-35}{1,-9}{2}" & vbCrLf, _
        operation, mBuffer, occupiedBufferCount)
  End Sub

End Class

      </source>


Producer and Consumer with Unsynchronized Integer Buffer

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

  Shared Sub Main()
     " create shared object used by threads
     Dim holdInteger As New UnsynchronizedIntegerBuffer()
     " Random object used by each thread
     Dim randomObject As New Random()
     " create Producer and Consumer objects
     Dim producer As New CProducer(holdInteger, randomObject)
     Dim consumer As New CConsumer(holdInteger, randomObject)
     " create threads for producer and consumer  
     " set delegates for each thread
     Dim producerThread As New Thread(AddressOf producer.Produce)
     Dim consumerThread As New Thread(AddressOf consumer.Consume)
     " name each thread
     producerThread.Name = "Producer"
     consumerThread.Name = "Consumer"
     " start each thread
     producerThread.Start()
     consumerThread.Start()
  End Sub " Main

End Class " Produces integers from 1 to 4 and places them in unsynchronized buffer. Public Class CProducer

  Private sharedLocation As UnsynchronizedIntegerBuffer
  Private randomSleepTime As Random
  Public Sub New(ByVal sharedObject As _
     UnsynchronizedIntegerBuffer, ByVal randomObject As Random)
     sharedLocation = sharedObject
     randomSleepTime = randomObject
  End Sub
  Public Sub Produce()
     Dim count As Integer
     For count = 1 To 4
        Thread.Sleep(randomSleepTime.Next(3000))
        sharedLocation.Buffer = count
     Next
     Console.WriteLine(Thread.CurrentThread.Name & _
        " done producing." & vbCrLf & "Terminating " & _
        Thread.CurrentThread.Name & ".")
  End Sub

End Class " Consumes 4 integers from unsynchronized buffer. Public Class CConsumer

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

End Class " Definition of a shared integer without synchronization mechanisms. Public Class UnsynchronizedIntegerBuffer

  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>


Thread Producer and Consumer

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

   Public Buffer As Integer
   Public BufferEmpty As Boolean = True
   Public MonitorLock As Object = New Object()
   Sub Producer()
       Dim Value As Integer = 0
       Do
           Monitor.Enter(MonitorLock)
           If (BufferEmpty) Then
               BufferEmpty = False
               Buffer = Value
               If (Value = 0) Then
                   Value = 1
               Else
                   Value = 0
               End If
               Console.WriteLine("Producer: " & Buffer)
           End If
           Monitor.Exit(MonitorLock)
       Loop While (True)
   End Sub
   Sub Consumer()
       Dim Value As Integer
       Do
           Monitor.Enter(MonitorLock)
           If (Not BufferEmpty) Then
               BufferEmpty = True
               Thread.CurrentThread.Sleep(1000)
               Value = Buffer
               Console.WriteLine("Consumer: " & Value)
           End If
           Monitor.Exit(MonitorLock)
       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>