Description:
The Attached code demonstrates important concept in multithreading, which is Synchronization.
I am calling a group of two text boxes and a label as a two counter as in (FirstTwoCounter, SecondTwoCounter, ThirdTwoCounter, etc.). I have five such twocounters.
Textboxes in FirstTwoCounter are incremented by thread FirstTwoCounterThread (it actually calls IncrementFirstTwoCounter function). Similarly textboxes in SecondTwoCounter are incremented by thread SecondTwoCounterThread (it actually calls IncrementSecondTwoCounter function) and so on.
I have a thread called WatchThread, apparently it looks like it does a needless job, which watches each of the twocounters and sees if their count is out of sync.This thread increments a static variable NoOfUnsyncs which keeps track of count of total unsyncs in any of the two counters and displays in a text box.
If you run this code surprisingly you would see that there are some unsyncs. Reason being,when there are multiple threads you never know when a thread is stopped and at what point of line of execution.For example it would happen that execution is stopped in IncrementFirstTwoCounter function after execution of the line txtFirstTwoCounter1.Text = Int32.ToString(FirstTwoCounterCnt1 ++) and watcher thread would have been called. At this point watcher thread would see that. FirstTwoCounterCnt1++ and FirstTwoCounterCnt2++ are out of sync . Preventing this kind of collision is simply a matter of putting a lock on a resource when one thread is using it. The first thread that accesses a resource locks it, and then the other threads cannot access that resource until it is unlocked To achieve this compile the code by using Monitor.Enter(this) and Monitor.Exit(this) between critical section.Now when you run the app and click on start button you would see that NofUnsyncs remains 0. I have already put this code in all five incremental function and watchcounter function.you just need to uncomment this and compile and run.
NOTE:
If you don't see unsync being incremented initially wait for sometime or try maximizing the form and then minimizing it.
What is needed to compile?
.NET SDK
How to Compile?
vbc /r:System.dll /r:System.winforms.dll /r:System.drawing.dll/r:Microsoft.win32.interop.dll Sync_thread2.vb
Code:
Imports System
Imports System.Drawing
'using System.Collections;
Imports System.ComponentModel
Imports System.WinForms
'using System.Data;
Imports System.Threading
Namespace synchronization
' <summary>
Public Class Form1
Inherits System.WinForms.Form
' <summary>
' Required designer variable.
' </summary>
Private components As System.ComponentModel.Container
Private WithEvents cmdExit As System.WinForms.Button
Private label11 As System.WinForms.Label
Private label8 As System.WinForms.Label
Private txtFifthTwoCounter2 As System.WinForms.TextBox
Private txtFifthTwoCounter1 As System.WinForms.TextBox
Private label4 As System.WinForms.Label
Private label10 As System.WinForms.Label
Private label9 As System.WinForms.Label
Private txtFourthTwoCounter2 As System.WinForms.TextBox
Private txtFourthTwoCounter1 As System.WinForms.TextBox
Private txtThirdTwoCounter2 As System.WinForms.TextBox
Private WithEvents label7 As System.WinForms.Label
Private txtNoOfUnsync As System.WinForms.TextBox
Private WithEvents cmdStart As System.WinForms.Button
Private label6 As System.WinForms.Label
Private label5 As System.WinForms.Label
Private txtThirdTwoCounter1 As System.WinForms.TextBox
Private label3 As System.WinForms.Label
Private txtSecondTwoCounter2 As System.WinForms.TextBox
Private txtSecondTwoCounter1 As System.WinForms.TextBox
Private label2 As System.WinForms.Label
Private txtFirstTwoCounter2 As System.WinForms.TextBox
Private txtFirstTwoCounter1 As System.WinForms.TextBox
Private label1 As System.WinForms.Label
'Counter variables for FirstTwoCounter
'will be incremented by FirstTwoCounter Thread
Private FirstTwoCounterCnt1 As System.Int32 = 0
Private FirstTwoCounterCnt2 As System.Int32 = 0
'Counter variables for SecondTwoCounter
'will be incremented by SecondTwoCounter Thread
Private SecondTwoCounterCnt1 As System.Int32 = 0
Private SecondTwoCounterCnt2 As System.Int32 = 0
'Counter variables for ThirdTwoCounter
'will be incremented by ThirdTwoCounter Thread
Private ThirdTwoCounterCnt1 As System.Int32 = 0
Private ThirdTwoCounterCnt2 As System.Int32 = 0
'Counter variables for FourthTwoCounter
'will be incremented by FourthTwoCounter Thread
Private FourthTwoCounterCnt1 As System.Int32 = 0
Private FourthTwoCounterCnt2 As System.Int32 = 0
'Counter variables for FifthTwoCounter
'will be incremented by FifthTwoCounter Thread
Private FifthTwoCounterCnt1 As System.Int32 = 0
Private FifthTwoCounterCnt2 As System.Int32 = 0
'Thread For FirstTwoCounter
Private FirstTwoCounterThread As System.Threading.Thread
'Thread For SecondTwoCounter
Private SecondTwoCounterThread As System.Threading.Thread
'Thread For ThirdTwoCounter
Private ThirdTwoCounterThread As System.Threading.Thread
'Thread For FourthTwoCounter
Private FourthTwoCounterThread As System.Threading.Thread
'Thread For FifthTwoCounter
Private FifthTwoCounterThread As System.Threading.Thread
'Watches the counters on all the threads and displays whethere the pairs of counters are equal or out of sync
Private WatchThread As System.Threading.Thread
Private Shared NoOfUnsync As System.Int32 = 0
Public Sub New()
'
' Required for Windows Form Designer support
'
InitializeComponent()
'
' TODO: Add any constructor code after InitializeComponent call
'
txtNoOfUnsync.Text = Int32.ToString(NoOfUnsync)
FirstTwoCounterThread = New Thread(New ThreadStart
IncrementFirstTwoCounter))
SecondTwoCounterThread = New Thread(New ThreadStart(IncrementSecondTwoCounter))
ThirdTwoCounterThread = New Thread(New ThreadStart(IncrementThirdTwoCounter))
FourthTwoCounterThread = New Thread(New ThreadStart(IncrementFourthTwoCounter))
FifthTwoCounterThread =