Geeks With Blogs
Brian Biales because blogging is just the easiest way to remember things

I was speaking with a colleague earlier today about a potential threading issue in his code.  I suggested serializing access to his object to ensure two threads are not using it at the same time, as that could corrupt the processing.  Being a relative “old-timer” who’s largest mutithreading applications were written in Visual C++ v 5 and 6, I remember heavy use of the CriticalSection, and wrapping the lock/unlock of critical sections in a class to ensure that every lock eventually got unlocked.  We developed the class to ensure matched Enters and Exits after many hours of debugging deadlocks in the early development stages.  But I digress a little…  .NET has wrapped it all up for us now, and I thought I’d just right this up for the next time someone asks me about it.

The Monitor class (in System.Threading) can help synchronize access to a particular object or resource, ensuring that once a thread has access, it will remain the only thread with access until the lock is released.  To use it, create an object that is shared with all the threads that will be accessing the resource (perhaps a static member of a class they all use).  It doesn’t have to be any particular type of object.  As a matter of fact, it could be declared and initialized (in C#) as:

Object oLocker = new Object();

Now if you want exclusive access to the resource, you can use the Monitor class like this:

Monitor.Enter(oLocker);

If another thread has already “entered” for this object, your thread will block until that other thread calls Monitor.Exit(oLocker).  Many threads can be blocked at once.  When the owning thread calls the Monitor.Exit(), one of those waiting threads is allowed access.  I believe it is FIFO, but I don’t know if that is guaranteed.

A thread can actually end up calling Monitor.Enter() multiple times on the same object.  If the thread already owns the lock, then this will simply increment a lock count.  You MUST call Exit for each time you call Enter.  Otherwise you WILL cause a deadlock in your program. 

You could make sure you call Exit yourself, by using the try / finally construct. You would Call Monitor.Enter() in the try block, and call Monitor.Exit()  in the finally block.  So even if your code throws an unhandled exception, the finally code block would exit the lock. 

The C# and VB.NET languages have macros to help you ensure you unlock at the end.  C# uses lock, VB.Net uses SyncLock.

In C# you would use lock like this:

lock(oLocker)
{
    <put your synchronized code here>
}

What lock does is call Monitor.Enter() on the object in the parenthesis, and add a finally block for you at the end that calls Monitor.Exit().  This makes your code easier to read and easier to write.

SyncLock does basically the same thing in VB.NET.  The syntax is slightly different.

Here is a VB.Net example:

SyncLock oLocker
    <put your synchronized code here>
End SyncLock

 

Any code that uses lock or SyncLock (or Monitor.Enter()/Monitor.Exit()) on a particular object can run with the assurance that no other thread will interfere with it. 

Posted on Friday, June 19, 2009 6:39 PM .NET , C# , Visual Studio 2005 | Back to top


Comments on this post: lock, SyncLock, and the Monitor class – ensuring “single thread” access to resources in a multithreaded application

# re: lock, SyncLock, and the Monitor class – ensuring “single thread” access to resources in a multithreaded application
Requesting Gravatar...
Gr8 ariticle.....

I am Impressed!
Left by Aditya Gaurav Daruka on Aug 05, 2009 2:33 AM

# re: lock, SyncLock, and the Monitor class – ensuring “single thread” access to resources in a multithreaded application
Requesting Gravatar...
didn't work out 4 me....

can;t say i/m not impressed but instead of lock i've used MUTEX..
Left by ashish on Aug 19, 2009 10:00 AM

# re: lock, SyncLock, and the Monitor class – ensuring “single thread” access to resources in a multithreaded application
Requesting Gravatar...
Ashish, sorry it didn't work for you, that is odd. I should provide some good source code, I know a coworker tried to use this and did not do it properly. The mistake made was to create a new instance of an object on the stack, and lock that. Well, the lock will never fail, since it is a new object and nobody else has access to it. The object used to lock/synchronize must be a static or at least a common object that all the methods that must by synchronized have access to. If only synchronizing access to the same instance of an object, you could even use lock(this) {...}. So threads accessing other objects will not be blocked, but if two threads try to access methods of the same object, and those methods both start with lock(this){...} then one will block. Hope that helps.
Left by Brian Biales on Aug 19, 2009 10:35 AM

# re: lock, SyncLock, and the Monitor class – ensuring “single thread” access to resources in a multithreaded application
Requesting Gravatar...
Thx! Worked great for me :P
Left by Yan on Sep 01, 2009 10:59 AM

# re: lock, SyncLock, and the Monitor class – ensuring “single thread” access to resources in a multithreaded application
Requesting Gravatar...
Great walkthrough. This saved me a great deal of time. Thanks for sharing this.
Left by Tony on Jan 07, 2011 12:24 PM

# re: lock, SyncLock, and the Monitor class – ensuring “single thread” access to resources in a multithreaded application
Requesting Gravatar...
Thax !! Worked for me too!!
Left by Anil on Dec 23, 2011 7:47 AM

Your comment:
 (will show your gravatar)


Copyright © Brian Biales | Powered by: GeeksWithBlogs.net