Producer and Consumer with Synchronized Integer Buffer : Producer Consumer « Thread « VB.Net






Producer and Consumer with Synchronized Integer Buffer

Producer and Consumer with Synchronized Integer Buffer
' *************************************************************
' * (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
           
       








Related examples in the same category

1.Thread Producer and ConsumerThread Producer and Consumer
2.Producer and Consumer with Unsynchronized Integer BufferProducer and Consumer with Unsynchronized Integer Buffer