VB.Net/Thread/Buffer

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

Circular Buffer Demo

Imports System
Imports System.Threading
Public Class MainClass
   Shared Sub Main()
      " create shared object
      Dim sharedLocation As New CHoldIntegerSynchronized()
      sharedLocation.CreateStateOutput()
      " Random object used by each thread
      Dim randomObject As New Random()
      " create CProducer and CConsumer objects
      Dim producer As New CProducer(sharedLocation, randomObject)
      Dim consumer As New CConsumer(sharedLocation, randomObject)
      " create threads
      Dim producerThread As New Thread(AddressOf producer.Produce)
      Dim consumerThread As New Thread(AddressOf consumer.Consume)
      " name threads
      producerThread.Name = "Producer"
      consumerThread.Name = "Consumer"
      " start threads
      producerThread.Start()
      consumerThread.Start()
   End Sub " Main
End Class
Public Class CConsumer
   Private sharedLocation As CHoldIntegerSynchronized
   Private randomSleepTime As Random
   " constructor
   Public Sub New(ByVal sharedObject As CHoldIntegerSynchronized, _
      ByVal randomObject As Random)
      sharedLocation = sharedObject
      randomSleepTime = randomObject
   End Sub
   Public Sub Consume()
      Dim count, sum As Integer
      For count = 1 To 10
         Thread.Sleep(randomSleepTime.Next(1, 3000))
         sum += sharedLocation.Buffer
      Next
      Console.WriteLine( "Total " & _
         Thread.CurrentThread.Name & " consumed: " & sum & vbCrLf & _
         Thread.CurrentThread.Name & " terminated." )
   End Sub
End Class
Public Class CHoldIntegerSynchronized
   Private mBuffer As Integer() = {-1, -1, -1}
   Private occupiedBufferCount As Integer
   Private readlocation, writeLocation As Integer
   Public Sub New()
   End Sub " New
   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
            CreateStateOutput() 
            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
            CreateStateOutput() 
            Monitor.Pulse(Me)
         End SyncLock
      End Set
   End Property " Buffer
   Public Sub CreateStateOutput()
      Dim i As Integer
      Console.WriteLine( "(buffers occupied: " & _
         occupiedBufferCount & ")" & vbCrLf & "buffers: " )
      For i = 0 To mBuffer.GetUpperBound(0)
         Console.Write( " " & mBuffer(i) & "  " )
      Next
      For i = 0 To mBuffer.GetUpperBound(0)
         Console.Write( "---- " )
      Next

      For i = 0 To mBuffer.GetUpperBound(0)
         If (i = writeLocation AndAlso _
            writeLocation = readlocation) Then
            Console.Write( " WR  " )
         ElseIf i = writeLocation Then
            Console.Write( " W   " )
         ElseIf i = readlocation Then
            Console.Write( "  R  " )
         Else
            Console.Write( "     " )
         End If
      Next
   End Sub
End Class
Public Class CProducer
   Private sharedLocation As CHoldIntegerSynchronized
   Private randomSleepTime As Random
   Public Sub New(ByVal sharedObject As CHoldIntegerSynchronized, _
      ByVal randomObject As Random)
      sharedLocation = sharedObject
      randomSleepTime = randomObject
   End Sub " New
   Public Sub Produce()
      Dim count As Integer
      For count = 11 To 20
         Thread.Sleep(randomSleepTime.Next(1, 3000))
         sharedLocation.Buffer = count
      Next
      Console.WriteLine( Thread.CurrentThread.Name & _
         " done producing. " & vbCrLf & _
         Thread.CurrentThread.Name & " terminated." )
   End Sub
End Class