Following are the ways to handle Threads Synchronization in C#
1)Using Lock Mechanism with keyword "Lock"
2)Using Monitors
3)Using Wait and Event Handles
Thread Synchronization using Lock Key word:
Using "Lock" keyword allows only one thread to execute a piece of code while the other threads keep waiting until the lock is released. Lock takes object as an argument which is derived from System.object.
Eg:
1)
class Synchronization
{
private object objLock = new object();
void SampleMethod()
{
//Other threads keep waiting here until the other thread finishes the execution
lock (objLock)
{
//Block which need to be accessed by only one thread at a time
}
}
}
2) If we have multiple instances of the same class, the above example will not work as each instance(with Mutliple threads ofcourse) might have acquired lock separately.
To avoid this we need to declare the Object as "staic" and to avoid any misuse of the object(like some one assigning that object to something else) we can use "readonly" field.
Eg: so the above example is changed as below
class Synchronization
{
private static readonly object objLock = new object();
void SampleMethod()
{
//Other threads keep waiting here until the other thread finishes the execution
lock (objLock)
{
//Block which need to be accessed by only one thread at a time
}
}
}
Eg:
1)
class Synchronization
{
private object objLock = new object();
void SampleMethod()
{
//Other threads keep waiting here until the other thread finishes the execution
lock (objLock)
{
//Block which need to be accessed by only one thread at a time
}
}
}
2) If we have multiple instances of the same class, the above example will not work as each instance(with Mutliple threads ofcourse) might have acquired lock separately.
To avoid this we need to declare the Object as "staic" and to avoid any misuse of the object(like some one assigning that object to something else) we can use "readonly" field.
Eg: so the above example is changed as below
class Synchronization
{
private static readonly object objLock = new object();
void SampleMethod()
{
//Other threads keep waiting here until the other thread finishes the execution
lock (objLock)
{
//Block which need to be accessed by only one thread at a time
}
}
}
Thread Synchronization using Monitor:
Monitor is same as Lock ,infact Lock uses Monitor mechanism internally. Monitor class is predefined in C#. Net it has two methods Enter and Exit. Enter allows only one thread to enter the piece of code.
class Synchronization
{
object monitorObj = new object();
public void SampleMethod()
{
System.Threading.Monitor.Enter(monitorObj);
//Piece of code which needs to be Synchronized
System.Threading.Monitor.Exit(monitorObj);
}
}
Lock are relatively more used than monitor as it is concise and easy to use.
Thread Synchronization using Events and Wait Handles:
The above two Process (Lock and Monitor) is used for Locking a Piece of code under the method in which the lock is specified but it is not usefull when we want the Lock the thread accross series of methods. For this we need to use Events mechanism in C#. There are two states for events "signalled " and "un-signalled", by default the events are in un-signalled state.There are two built in events in C# .
1) AutoResetEvent
2) Manual ResetEvent
Thread is activated only if we change the state from un-signalled state to signalled state
(i)AutoResetEvent:
In AutoResetEvent, once execution is completed it automatically changes its state back to un-signalled . So once a new thread comes again at the same block it again starts executing (since it is in un-signalled state) .
(ii)ManualResetEvent:
In ManualResetEvent ,once execution is completed it keeps the last state untill a explicit reset is done for that event. Let say event initially is in un-signalled state and one thread executes the process and set it to as Signalled state, so all the threads coming after this thread will never executes the same process as it is already set as signalled state by first thread until it is explicitly Reset.
Example:
class AutoResetEventExample
{
private System.Threading.AutoResetEvent autoEvent;
public void function1()
{
// One thread has entered
//Do the processing
//blocks the Thread untill it receives a signal
autoEvent.WaitOne();
//Starts processing once its receives the Signal
}
void Main()
{
//Creating a AutoResetEvent by initializing the event in un-signalled state(by passing false)
autoEvent = new System.Threading.AutoResetEvent(false);
//Creating a new thread
Thread t = new Thread(function);
t.Start();
Thread.Sleep(1000);
//Again signalling the worker thread as it is back to un-signalled state
autoEvent.Set();
}
}
