Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / programming / threads

Multithreading: Which lock object should I use?

3.00/5 (8 votes)
6 Sep 2010CPOL1 min read 25.1K  
Which lock object should I use?

The lock keyword locks a specified code block so two threads can't process the same code block at the same time. When one threads exits the locked block, another thread can enter the locked code block. The Monitor class offers the same functionality, but you specify the start and end of the locked code block with Monitor.Enter and Monitor.Exit. For both techniques, you need a variable to lock on. A common pattern is to lock on this for instance data in a class or typeof(type) for static data.

C#
using System; 
using System.Threading; 

public class LockObject
{
    private static int counter = 0;

    public static void MonitorIncrement()
    {
        Monitor.Enter(typeof(LockObject));
        counter++;
        Monitor.Exit(typeof(LockObject));
    }

    public static void LockIncrement()
    {
        lock (typeof(LockObject))
        {
            counter++;
        }
    }
}

The problem with this is, this typeof(type) could also be the lock object in an entirely different synchronization block outside the class in an unrelated code block. The result would be that two completely different synchronization blocks that synchronize two different sets of data can block each other. The same thing can happen if you use a string as a lock variable, because all the strings refer to the same instance. These problems can be solved with a private read-only field to lock on!

C#
public class LockObject
{
    private static int counter = 0;
    private readonly static object syn = new object();

    public static void MonitorIncrement()
    {
        Monitor.Enter(syn);
        counter++;
        Monitor.Exit(syn);
    }

    public static void LockIncrement()
    {
        lock (syn)
        {
            counter++;
        }
    }
}

The lock object is private so it can't be used by code blocks outside the class as lock object! The read-only attribute prevents the variable from changes. The problem in the samples can also be solved by using Interlocked.Increment! It is only used to show the problem on a simple example!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)