VB.Net/Thread/Producer Consumer — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Версия 16:40, 26 мая 2010
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
Producer and Consumer with Unsynchronized Integer Buffer
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
Thread Producer and Consumer
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