views:

518

answers:

3

When you lock an object is that object locked throughout the whole application?

For Example, this snippet from C# 3.0 in a Nutshell Section 19.6.1 "Thread Safety and .NET Framework Types":

static void AddItems(  )
  {
    for (int i = 0; i < 100; i++)
      lock (list)
        list.Add ("Item " + list.Count);

    string[] items;
    lock (list) items = list.ToArray(  );
    foreach (string s in items) Console.WriteLine (s);
  }

Does the first lock:

lock (list)
        list.Add ("Item " + list.Count);

prevent another thread from accessing:

lock (list) items = list.ToArray(  );

or can both be executed at the same time?

And does the CLR automatically make your static methods thread safe? Or is that up to the developer?

Thanks, John

+3  A: 

The CLR doesn't automatically make static methods thread-safe; you must do it yourself.

lock(list) uses that object as a lock, so if a different thread reaches another point with lock(list) (with the same 'list' object), the other thread will block until the first thread releases the lock.

To be clear, lock(foo) doesn't "lock the foo object", rather it acquires the lock associated with the foo object so that the critical section (the statement in the construct "lock(o) stmt") runs only when the current thread has acquired the lock.

Brian
Thanks for your quick response!
John
+3  A: 
class UsefulStuff {
    object _TheLock = new object { };
    public void UsefulThingNumberOne() {
        lock(_TheLock) {
            //CodeBlockA
        }
    }
    public void UsefulThingNumberTwo() {
        lock(_TheLock) {
            //CodeBlockB
        }
    }
}

CodeBlockA and CodeBlockB are prevented from executing at the same time in different threads, because they are both locked on the same object instance _TheLock.

The methods on _TheLock itself are completely unaffected.

Justice
Thanks for clearing it up for me.
John
+4  A: 

One other thing to note is that static constructors ARE executed in a threadsafe way by the runtime. If you are creating a singleton and declare it as:

public class Foo
{
    private static Foo instance = new Foo();

    public static Foo Instance
    {
        get { return instance; }
    }
}

Then it will be threadsafe. If however, you instantiate a new Foo inside the Instance getter, then you would need to write your own thread safety (ie. lock an object)

Richard Szalay