APEXA, LLC
Blog Gallery Contact

Thread Synchronization lock, Monitor, Interlocked

Blog Date: Friday, May 8, 2009 - Discuss below!

 Recent Blogs << Back

ASP.NET MVC versus Web Forms vs Silverlight 4/21/2009

Unit Testing with Dependency Injection 4/25/2009

ASP.NET HttpHandlers and HttpModules 5/5/2009

 More...
 

IT Jobs Hiring


Senior .NET Application Developer (Chicago - Loop) North Chicago, IL

*****SQL Server DBA 2005/2008 Immediate**** (San Diego CA 92101 ) San Diego, CA

Process Engineer II - First Data Atlanta North, GA

More jobs...
 

I've been reading a lot about thread synchronization to understand the lower-level intracacies of how the .NET framework handles threading issues. Most of you may be most familiar with the lock() statement and use it pretty loosely.

  • But what's really happening under the hood?
  • What are some threading alternatives?
    • What is System.Threading.Monitor?
    • What about System.Threading.Interlocked?

Well, under the hood, a lock function, ie,

lock(something)
{
    // do work
}

is actually performing this:

object tmpObject = synchHandle;
System.Threading.Monitor.Enter(tmpObject);
try

    total++;
}
finally
{
    System.Threading.Monitor.Exit(tmpObject);
}

But, then they have a neat little function for timeouts. Say you have a resource that you need to access with thread safety. But that function hangs. You cannot release the lock. Now you have a dealock, and nothing else can access that function until it is released. That is why you have the Monitor.TryEnter function which has a timeout feature.

    if (!Monitor.TryEnter(syncHandle, 1000)) // wait 1 second
        throw new PreciousResourceException
            ("Could not enter critical section");
    try
    {
        total++;
    }
    finally
    {
        Monitor.Exit(syncHandle);
    }

The article I was reading had a neat little way of wrapping it all up into this neat little functionality.

public sealed class LockHolder<T> : IDisposable where T : class
{
    private T handle;
    private bool holdsLock;

    public LockHolder(T handle, int milliSecondTimeout)
    {
        this.handle = handle;
        holdsLock = System.Threading.Monitor.TryEnter(
            handle, milliSecondTimeout);
    }

    public bool LockSuccessful
    {
        get { return holdsLock; }
    }

    #region IDisposable Members
    public void Dispose()
    {
        if (holdsLock)
            System.Threading.Monitor.Exit(handle);
        // Don’t unlock twice
        holdsLock = false;
    }
    #endregion
}

And now you can wrap it all up nicely with reusability as such:

using (LockHolder<object> lockObj = new LockHolder<object>

    (lockHandle, 1000))
{
    if (lockObj.LockSuccessful)
    {
        // work elided
    }
}

Interlocking is for manipulating objects safely such as incrementing. In the words of Bill Wagner:

For most common synchronization problems, examine the Interlocked class to see if it can be used to provide the capabilities you need. With many single operations, it can. When it can’t your first choice is the lock() statement. Only look beyond those when you need some special purpose locking capability.

For more information about Interlocked.Decrement() and Interlocked.Decrement()and  Interlocked.Exchange() functions. The Pulse and Wait methods to implement a consumer / producer design. And more about the  ReaderWriterLockSlim class, read the article at:
http://www.informit.com/articles/article.aspx?p=1231461



Friday, May 08, 2009 2:23:51 PM

Home | Gallery | Contact | IT Consulting | Web Marketing | Search Engine Optimization | Web Design & CMS | My Blog on C# .NET

Site Map | Copyright 2007 Web Design web design | Developed by APEXA, LLC

APEXA, LLC