lock Statement
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:
 
lock(expression) statement_block

Remarks

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

Example 1

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");
   }
   public static void Main() 
   {
      ThreadTest b = new ThreadTest();
      Thread t = new Thread(new ThreadStart(b.runme));
      t.Start();
   }
}

Example 2

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 
{
   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 (this)
      {
         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 
{
   public 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();
      }
   }
}