lock and deadlocks (basics)

The main problem of multithreading is sharing data. You cannot access the same data from two different threads at the same time unless they are both reading. Use the lock() command to deal with sharing issues. It is nearly straightforward, just make sure you don’t cause deadlocks.

static void DeadLock() {
    object A = new object();
    object B = new object();

    Task.Factory.StartNew(() => {
        lock (A) {
            Thread.Sleep(1000);
            lock (B) Console.WriteLine("locked A, then B");
        }
    });

    Task.Factory.StartNew(() => {
        lock (B) {
            lock (A) Console.WriteLine("locked B, then A");
        }
    });

    Console.ReadLine();
} //

The example shows a simplified deadlock situation. Two tasks (=threads) wait for access to resources, in this case the objects A and B. The first task blocks access to object A. In the meantime the second task blocks access to object B and then asks for access to A. But A is blocked. The next step is that the first task finishes sleeping and asks for access to B. But B was already blocked by the second task. This results in a classical deadlock situation.

The example uses tasks, you can expect each task to use another thread. But this does not have to be the case.  Don’t expect to be lucky, it won’t work in the long run. It is necessary to assume that each task equals a new thread.
A lock() on an object can be re-entered multiple times by the same thread.

To avoid deadlocks you have to make sure that locks are requested in the same order. And you should only use locks on private objects and avoid “this” as the locking object.

static void Lock() {
    object o = new object();
    bool locked = false;

    try {
        Monitor.Enter(o, ref locked);

        Console.WriteLine("bla bla bla");
        Thread.Sleep(1000); // do something
    }
    finally {
        if (locked) Monitor.Exit(o);
    }

    // equals

    lock (o) {
      Console.WriteLine("bla bla bla");
      Thread.Sleep(1000); // do something
    }

    Console.ReadLine();
} //

The lock command is a shortcut replacing the above code. It uses the Monitor class. Generally there is no reason to not use lock() even though the Monitor class offers a lot of extras.

Advertisements

About Bastian M.K. Ohta

Happiness only real when shared.

Posted on December 10, 2013, in Basic, C#, Threading and tagged , , , , , . Bookmark the permalink. 1 Comment.

  1. Hello
    nice post on deadlocks. If you have deep interest in threaded related topics, especially on .net, I would like to have your input on my blog @ http://dupdob.wordpress.com/
    Keep the good work anyway

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: