Click to Rate and Give Feedback
MSDN
MSDN Library
Visual Studio 2005
Visual Studio
Visual C#
C# Reference
C# Keywords
Statement Types
 lock Statement
Collapse All/Expand All Collapse All
This page is specific to
Microsoft Visual Studio 2005/.NET Framework 2.0

Other versions are also available for the following:
C# Language Reference
lock Statement (C# Reference)

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. This statement takes the following form:

Object thisLock = new Object();
lock (thisLock)
{
    // Critical code section
}

For more information, see Thread Synchronization (C# Programming Guide).

lock ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread attempts to enter a locked code, it will wait, block, until the object is released.

The section Threading (C# Programming Guide) discusses threading.

lock calls Enter at the beginning of the block and Exit at the end of the block.

In general, avoid locking on a public type, or instances beyond your code's control. The common constructs lock (this), lock (typeof (MyType)), and lock ("myLock") violate this guideline:

  • lock (this) is a problem if the instance can be accessed publicly.

  • lock (typeof (MyType)) is a problem if MyType is publicly accessible.

  • lock(“myLock”) is a problem since any other code in the process using the same string, will share the same lock.

Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.

The following sample shows a simple use of threads in C#.

// statements_lock.cs
using System;
using System.Threading;

class ThreadTest
{
    public void RunMe()
    {
        Console.WriteLine("RunMe called");
    }

    static void Main()
    {
        ThreadTest b = new ThreadTest();
        Thread t = new Thread(b.RunMe);
        t.Start();
    }
}

Output

RunMe called

The following sample uses threads and lock. As long as the lock statement is present, the statement block is a critical section and balance will never become a negative number.

// statements_lock2.cs
using System;
using System.Threading;

class Account
{
    private Object thisLock = new Object();
    int balance;

    Random r = new Random();

    public Account(int initial)
    {
        balance = initial;
    }

    int Withdraw(int amount)
    {

        // This condition will never be true unless the lock statement
        // is commented out:
        if (balance < 0)
        {
            throw new Exception("Negative Balance");
        }

        // Comment out the next line to see the effect of leaving out 
        // the lock keyword:
        lock(thisLock)
        {
            if (balance >= amount)
            {
                Console.WriteLine("Balance before Withdrawal :  " + balance);
                Console.WriteLine("Amount to Withdraw        : -" + amount);
                balance = balance - amount;
                Console.WriteLine("Balance after Withdrawal  :  " + balance);
                return amount;
            }
            else
            {
                return 0; // transaction rejected
            }
        }
    }

    public void DoTransactions()
    {
        for (int i = 0; i < 100; i++)
        {
            Withdraw(r.Next(1, 100));
        }
    }
}

class Test
{
    static void Main()
    {
        Thread[] threads = new Thread[10];
        Account acc = new Account(1000);
        for (int i = 0; i < 10; i++)
        {
            Thread t = new Thread(new ThreadStart(acc.DoTransactions));
            threads[i] = t;
        }
        for (int i = 0; i < 10; i++)
        {
            threads[i].Start();
        }
    }
}

For more information, see the following sections in the C# Language Specification:

  • 5.3.3.18 Lock statements

  • 8.12 The lock statement

Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
See related Monitor Class      Chriswo2 ... Peter Huber   |   Edit   |   Show History
Be sure to check out the Monitor class too. If you want to lock an object in one method and release it in another, the Monitor class allows you to have the lock and unlock in different parts of the code.
Tags What's this?: Add a tag
Flag as ContentBug
Avoid lock(this), lock(typeof(MyType)) and lock(&quot;myLock&quot;)      David M. Kean - MSFT   |   Edit   |   Show History

As mentioned in the documentation, avoid using the lock keyword on a type, string or the this pointer. Locking on these objects can lead to threading issues.

For more information, see the following topic: http://msdn2.microsoft.com/en-us/ms182290.aspx.

Tags What's this?: Add a tag
Flag as ContentBug
Bug in demo code.      Lu Xin   |   Edit   |   Show History
The demo code needs mechanism (i.e. AutoResetEvent[]) to make sure all created threads ended before main process exit.
Tags What's this?: Add a tag
Flag as ContentBug
Why should we avoid using lock(this)?      sumitlathwal   |   Edit   |   Show History
A couple of more links on why lock(this) should be avoided:

http://www.toolazy.me.uk/template.php?content=lock(this)_causes_deadlocks.xml

http://srtsolutions.com/blogs/billwagner/archive/2007/09/09/why-lock-this-is-bad.aspx

Tags What's this?: lock (x) Add a tag
Flag as ContentBug
Lock the random numbers, beside the withdrawal also.      salutdd   |   Edit   |   Show History
The example doesn't pay attention, Random.Next is not thread-safe.
There are 10 threads all using the same "Random" object.
It should be ensured, there's always just one thread at a time generating a number.

public void DoTransactions()
{
for (int i = 0; i < 100; i++)
{
int amount;
lock(r)
{
amount = r.Next(1,00);
}
Withdraw(amount);
}
}
Tags What's this?: Add a tag
Flag as ContentBug
Processing
© 2009 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Site Feedback
Page view tracker