Monitor and lock in C#
Is your email address OK? You are signed up for our newsletters but your email address is either unconfirmed, or has not been reconfirmed in a long time. Please click here to have a confirmation email sent so we can confirm your email address and start sending you newsletters again. Alternatively, you can update your subscriptions.Introduction
When working with a multithreading application, it is very important for developers to handle multiple threads for a critical section of code.Monitor and lock is the way to provide thread safety in a multithreaded application in C#. Both provide a mechanism to ensure that only one thread is executing code at the same time to avoid any functional breaking of code.
Lock
Lock is the keyword in C# that will ensure one thread is executing a piece of code at one time. The lock keyword ensures that one thread does not enter a critical section of code while another thread is in that critical section.Lock is a keyword shortcut for acquiring a lock for the piece of code for only one thread.
Sample Code
Hide Copy Code
1. namespace Monitor_Lock
2. {
3. class Program
4. {
5. static readonly object _object = new object();
6.
7. static void TestLock()
8. {
9.
10. lock (_object)
11. {
12. Thread.Sleep(100);
13. Console.WriteLine(Environment.TickCount);
14. }
15. }
16.
17. static void Main(string[] args)
18. {
19. for (int i = 0; i < 10; i++)
20. {
21. ThreadStart start = new ThreadStart(TestLock);
22. new Thread(start).Start();
23. }
24.
25. Console.ReadLine();
26. }
27. }
28. } Output
Here we see astatic method "TestLock" that uses the lock statement on an object. When the methodTestLock is called many times on new threads, each invocation of the method accesses the threading primitives implemented by the lock.The
Main method creates ten new threads and then calls Start on each one. The method TestLock is invoked ten times, but the tick count shows the protected method region is executed sequentially, about 100 milliseconds apart.If another thread tries to enter a locked code, it will wait, block, until the object is released.
The
lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement and then releasing the lock.Monitor
Monitor provides a mechanism that synchronizes access to objects. It can be done by acquiring a significant lock so that only one thread can enter in a given piece of code at one time. Monitor is no different from lockbut the monitor class provides more control over the synchronization of various threads trying to access the same lock of code.Using a
monitor, it can be ensured that no other thread is allowed to access a section of application code being executed by the lock owner, unless the other thread is executing the code using a different locked object.The
Monitor class has the following methods for the synchronize access to a region of code by taking and releasing a lock:Monitor.EnterMonitor.TryEnterMonitor.Exit
Wait releases the
lock if it is held and waits to be notified. When Wait is notified, it returns and obtains the lock again. Both a Pulse and PulseAll signal for the next thread in the wait queue to proceed.The following is the syntax for using a monitor.
Hide Copy Code
1. try
2. {
3. int x = 1;
4.
5. Monitor.Enter(x);
6. try
7. {
8. // Code that needs to be protected by the monitor.
9. }
10. finally
11. {
12.
13. Monitor.Exit(x);
14. }
15. }
16. catch (SynchronizationLockException SyncEx)
17. {
18. Console.WriteLine("A SynchronizationLockException occurred. Message:");
19. Console.WriteLine(SyncEx.Message);
20. } Sample Code
Hide Shrink
Copy Code
Copy Code1. namespace Monitor_Lock
2. {
3. class Program
4. {
5. static readonly object _object = new object();
6.
7. public static void PrintNumbers()
8. {
9. Monitor.Enter(_object);
10. try
11. {
12. for (int i = 0; i < 5; i++)
13. {
14. Thread.Sleep(100);
15. Console.Write(i + ",");
16. }
17. Console.WriteLine();
18. }
19. finally
20. {
21. Monitor.Exit(_object);
22. }
23. }
24.
25. static void TestLock()
26. {
27.
28. lock (_object)
29. {
30. Thread.Sleep(100);
31. Console.WriteLine(Environment.TickCount);
32. }
33. }
34.
35. static void Main(string[] args)
36. {
37.
38.
39. Thread[] Threads = new Thread[3];
40. for (int i = 0; i < 3; i++)
41. {
42. Threads[i] = new Thread(new ThreadStart(PrintNumbers));
43. Threads[i].Name = "Child " + i;
44. }
45. foreach (Thread t in Threads)
46. t.Start();
47.
48. Console.ReadLine();
49. }
50. }
51. } Output
In C# 4.0 , overloaded function forMonitor.Enter(_object,ref _lockTaken).That acquires an exclusive lock and the specified object and automatically sets a value that indicates whether the lock was taken.
Hide Copy Code
1. class Program
2. {
3. static readonly object _object = new object();
4.
5. public static void PrintNumbers()
6. {
7. Boolean _lockTaken = false;
8.
9. Monitor.Enter(_object,ref _lockTaken);
10. try
11. {
12. for (int i = 0; i < 5; i++)
13. {
14. Thread.Sleep(100);
15. Console.Write(i + ",");
16. }
17. Console.WriteLine();
18. }
19. finally
20. {
21. if (_lockTaken)
22. {
23. Monitor.Exit(_object);
24. }
25. }
}
26. } Important Sticky
TheMonitor class is a static class and its instance cannot be created.The
Monitor class object uses the Monitor.Enter, Monitor.TryEnter, and Monitor.Exit methods. Once you have a lock on a code region, you can use the Monitor.Wait, Monitor.Pulse, and Monitor.PulseAllmethods.It is associated with an object on demand.
It is unbound, which means it can be called directly from any context.
Conclusion
Lock and monitor are basically used for the same purpose in multithreading, the difference is that only when we want more control over synchronization with multiple threads running for a specific section of code.


0 comments:
Post a Comment
Note: only a member of this blog may post a comment.