lock inside lock

C#Locking

C# Problem Overview


I'm wondering if this construction will cause an error:

lock(sync)
{
  // something
  lock(sync)
  {
    //something
    lock(sync)
    {
      //something
    }
  }
}

I've run this code, and it seems fine, but maybe in some circumstances an error may be thrown?

C# Solutions


Solution 1 - C#

lock is a wrapper for Monitor.Enter and Monitor.Exit:

> The lock keyword calls Enter at the start of the block and Exit at the end of the block. From the former's documentation:

From the documentation for Monitor.Enter:

> It is legal for the same thread to invoke Enter more than once without it blocking; however, an equal number of Exit calls must be invoked before other threads waiting on the object will unblock.

Because the calls to Enter and Exit are paired, your code pattern has well defined behaviour.

Note, however, that lock is not guaranteed to be an exception-less construct:

> A ThreadInterruptedException is thrown if Interrupt interrupts a thread that is waiting to enter a lock statement.

Solution 2 - C#

To explain why it is well-defined behavior and will never fail:

Aside: This answer has better details about how locks actually work

The lock occurs at the Thread level, so calling it a second time on the same thread will be redundant. I would think it would not have any performance penalty (although that would depend on how exactly the internals of .Net are written, so I can't guarantee that)

Many times you'd have a public function that calls another public function in your class, whom both need the lock when used seperately. If this was not allowed the following would fail:

private Dictionary<string, int> database = new Dictionary<string, int>();
private object databaseLock = new object();
public void AddOrUpdate(string item)
{
    lock (databaseLock)
    {
        if (Exists(item))
            database.Add(item, 1);
        else
            ++database[item];
    }
}
public bool Exists(string item)
{
    lock (databaseLock)
    {
        //... Maybe some pre-processing of the key or item...
        return database.ContainsKey(item);
    }
}

Solution 3 - C#

According to MSDN (see here and here) this is well-defined behaviour and causes no problem.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionreizalsView Question on Stackoverflow
Solution 1 - C#ta.speot.isView Answer on Stackoverflow
Solution 2 - C#ThymineView Answer on Stackoverflow
Solution 3 - C#YahiaView Answer on Stackoverflow