D
David
Below are three classes for a console application. If put into three
separate files, the sub main() will launch multiple threads adding and
removing the same value. At the end we expect the value for all
Balances to be 0. When using an Integer things work fine. LONGS do
not.
We are using the Interlocked methods. I believe the Interlocked.Add
method is not thread safe when using longs on 32bit systems.
We are aware of Interlocked.Read (new to dotnet 2.0) which is required
for longs on 32bit systems, but is the dotnet framework missing a trick
here as Microsoft have introduced a new method for reading but haven't
got the .Add method to work correctly.
Note: This works find on single core single procssors.
But does not on muli-core or dual-core or hyper-threaded pentium 4.
Option Explicit On
Option Strict On
Module Module1
Public Tellers(99) As Teller
Private Threads(99) As Threading.Thread
Sub Main()
For i As Integer = 0 To 99
Tellers(i) = New Teller
Next
Do
For i As Integer = 0 To 99
Dim t As New Threading.Thread(AddressOf
Tellers(i).DoWork)
Threads(i) = t
t.Start()
Next
For i As Integer = 0 To 99
Threads(i).Join()
Next
Dim B2 As Integer = BankInt.Balance
Console.WriteLine("Int Balance " & B2)
Dim B1 As Long = BankLong.Balance
Console.WriteLine("Long Balance " & B1)
Loop
End Sub
End Module
Option Explicit On
Option Strict On
Imports System.Threading
Public Class Teller
Public Sub DoWork()
For i As Integer = 1 To 100000
BankInt.Deposit(50)
BankInt.Withdraw(50)
BankLong.Deposit(50)
BankLong.Withdraw(50)
Next
End Sub
End Class
Option Explicit On
Option Strict On
Imports System.Threading
Public Class BankLong
Private Shared _balance As Long
Public Shared ReadOnly Property Balance() As Long
Get
Return Interlocked.Read(_balance)
End Get
End Property
Public Shared Sub Deposit(ByVal Amount As Long)
Interlocked.Add(_balance, Amount)
End Sub
Public Shared Sub Withdraw(ByVal Amount As Long)
Interlocked.Add(_balance, -Amount)
End Sub
End Class
Public Class BankInt
Private Shared _balance As Integer
Public Shared ReadOnly Property Balance() As Integer
Get
Return _balance
End Get
End Property
Public Shared Sub Deposit(ByVal Amount As Integer)
Interlocked.Add(_balance, Amount)
End Sub
Public Shared Sub Withdraw(ByVal Amount As Integer)
Interlocked.Add(_balance, -Amount)
End Sub
End Class
separate files, the sub main() will launch multiple threads adding and
removing the same value. At the end we expect the value for all
Balances to be 0. When using an Integer things work fine. LONGS do
not.
We are using the Interlocked methods. I believe the Interlocked.Add
method is not thread safe when using longs on 32bit systems.
We are aware of Interlocked.Read (new to dotnet 2.0) which is required
for longs on 32bit systems, but is the dotnet framework missing a trick
here as Microsoft have introduced a new method for reading but haven't
got the .Add method to work correctly.
Note: This works find on single core single procssors.
But does not on muli-core or dual-core or hyper-threaded pentium 4.
Option Explicit On
Option Strict On
Module Module1
Public Tellers(99) As Teller
Private Threads(99) As Threading.Thread
Sub Main()
For i As Integer = 0 To 99
Tellers(i) = New Teller
Next
Do
For i As Integer = 0 To 99
Dim t As New Threading.Thread(AddressOf
Tellers(i).DoWork)
Threads(i) = t
t.Start()
Next
For i As Integer = 0 To 99
Threads(i).Join()
Next
Dim B2 As Integer = BankInt.Balance
Console.WriteLine("Int Balance " & B2)
Dim B1 As Long = BankLong.Balance
Console.WriteLine("Long Balance " & B1)
Loop
End Sub
End Module
Option Explicit On
Option Strict On
Imports System.Threading
Public Class Teller
Public Sub DoWork()
For i As Integer = 1 To 100000
BankInt.Deposit(50)
BankInt.Withdraw(50)
BankLong.Deposit(50)
BankLong.Withdraw(50)
Next
End Sub
End Class
Option Explicit On
Option Strict On
Imports System.Threading
Public Class BankLong
Private Shared _balance As Long
Public Shared ReadOnly Property Balance() As Long
Get
Return Interlocked.Read(_balance)
End Get
End Property
Public Shared Sub Deposit(ByVal Amount As Long)
Interlocked.Add(_balance, Amount)
End Sub
Public Shared Sub Withdraw(ByVal Amount As Long)
Interlocked.Add(_balance, -Amount)
End Sub
End Class
Public Class BankInt
Private Shared _balance As Integer
Public Shared ReadOnly Property Balance() As Integer
Get
Return _balance
End Get
End Property
Public Shared Sub Deposit(ByVal Amount As Integer)
Interlocked.Add(_balance, Amount)
End Sub
Public Shared Sub Withdraw(ByVal Amount As Integer)
Interlocked.Add(_balance, -Amount)
End Sub
End Class