C# Lock Statement

by Sam Allen - Updated January 7, 2010

You want to see how the lock statement in the C# programming language can be applied to restrict access to a specific part of code to only one thread at a time. While the C# language provides the lock keyword, it is actually compiled to a lower-level implementation based on threading primitives. In this article, we delve into the lock statement in the C# language, and then go further into the intermediate representation as well as our understanding of time.

Using lock statement

In this first example, we see a static method A that uses the lock statement on an object. When the method A is called many times on new threads, each invocation of the method accesses the threading primitives implemented by the lock. Then, only one method A can call the statements protected by the lock at a single time, regardless of the thread count.

--- Program that uses lock statement (C#) ---

using System;
using System.Threading;

class Program
{
    static readonly object _object = new object();

    static void A()
    {
        // Lock on the readonly object.
        // ... Inside the lock, sleep for 100 milliseconds.
        // ... This is thread serialization.
        lock (_object)
        {
            Thread.Sleep(100);
            Console.WriteLine(Environment.TickCount);
        }
    }

    static void Main()
    {
        // Create ten new threads.
        for (int i = 0; i < 10; i++)
        {
            ThreadStart start = new ThreadStart(A);
            new Thread(start).Start();
        }
    }
}

--- Possible output of the program ---

28106840
28106949
28107043
28107136
28107246
28107339
28107448
28107542
28107636
28107745

Understanding program text. The program introduces two methods: the static method A, which is called from the Start method, and the Main entry point. The Main method creates ten new threads, and then calls Start on each of them. The method A is invoked ten times, but the tick count shows the protected method region is executed sequentially, approximately 100 milliseconds apart. If you remove the lock statement, the methods will be executed all at once, with no synchronization.

Intermediate representation

In this part, we examine the intermediate representation for the lock statement in the above example method A. In compiler theory, high-level source texts are translated to lower-level streams of instructions; the lock statement here is transformed into calls to the static methods Monitor.Enter and Monitor.Exit. Also, the lock is actually implemented with a try/finally construct.

--- Intermediate representation for method using lock ---

.method private hidebysig static void A() cil managed
{
    .maxstack 2
    .locals init (
        [0] object obj2)
    L_0000: ldsfld object Program::_object
    L_0005: dup
    L_0006: stloc.0
    L_0007: call void [mscorlib]System.Threading.Monitor::Enter(object)
    L_000c: ldc.i4.s 100
    L_000e: call void [mscorlib]System.Threading.Thread::Sleep(int32)
    L_0013: call int32 [mscorlib]System.Environment::get_TickCount()
    L_0018: call void [mscorlib]System.Console::WriteLine(int32)
    L_001d: leave.s L_0026
    L_001f: ldloc.0
    L_0020: call void [mscorlib]System.Threading.Monitor::Exit(object)
    L_0025: endfinally
    L_0026: ret
    .try L_000c to L_001f finally handler L_001f to L_0026
}

Theory of relativity

Here, we touch on the larger issue of synchronizing multiple threads in programs. By using the lock statement to synchronize accesses, we are in fact creating a communication between time and state. In other words, the state is connected to the concept of time and sequential accesses to the lock. In the Theory of Relativity, there is also a communication between time and state: this is the speed of light, which is a constant based on the relation of time and space. For a better description of how relativity mirrors concurrent synchronization, please see the book Structure and Interpretation of Computer Programs.

(See Structure and Interpretation of Computer Programs [Review].)

Summary

In this tutorial, we examined the lock statement in the C# programming language, first seeing its usage in an example program, and then describing this synchronization. Next, we stepped into the intermediate representation and its meaning in compiler theory. Finally, we related the Theory of Relativity and the complexities of the physical universe to the lock statement, using a top textbook.

(Do not copy this page.)

Dot Net Perls | Search
Threading | BackgroundWorker Tutorial | Sleep Method Pauses Programs | ThreadPool Usage | ThreadPool.SetMinThreads Method
C# | Obsolete Attribute | True and False | Gradient Tips | Catch Examples
© 2010 Sam Allen. All rights reserved.
Dot Net Perls | Sam Allen