由同一对象锁定的多个代码块

时间:2011-10-20 10:24:36

标签: c# .net multithreading c#-4.0

如果我有这样的话:

private readonly object objectLock = new object();

public void MethodA()
{
    lock(objectLock)
    {
      //do something
    }
}

public void MethodB()
{
    lock(objectLock)
    {
      //do something
    }
}

如果我有2个线程并且两个都同时进入,则第一个线程调用MethodA和第二个方法B.无论哪个首先到达并锁定objectLock,我假设另一个线程在那里等待,直到objectLock不再被锁定。 / p>

5 个答案:

答案 0 :(得分:5)

是的,你的解释是正确的 - 除非已经采取了锁定(在这种情况下,两个线程都在等待,并且任意一个线程在解锁时立即获得锁定。)

(稍微偏离主题)我建议如果他们做一些非常重要的事情,就不要锁定整个方法。尽量保持代码的“锁定”部分尽可能小和快。

答案 1 :(得分:5)

这是正确的。

然而,不是被锁定的objectLock(也不是对象),它是被锁定的代码块。

将传递给lock关键字的对象视为解锁多个门但只允许一次访问单个房间的密钥。

答案 2 :(得分:1)

你说得对!但要小心锁。锁定可能会让你的程序是线程安全的(手段,并发访问没有错误),但是需要花费更多的精力才能让你的程序在多内核系统上运行时发挥真正的优势。

答案 3 :(得分:0)

是的,你是正确的,因为Monitor.Enter和Monitor.Exit是在场景后面的同一个对象objectLock上调用的。记住它的同步代码块而不是objectLock。

答案 4 :(得分:0)

你是对的。如果这不可取,请考虑:

lock(objectLock)
{
  //do something
}

相当于:

Monitor.Enter(objectLock);
try
{
  //do something
}
finally
{
  Monitor.Exit(objectLock);
}

您可以将其替换为:

if(Monitor.TryEnter(objectLock, 250))//Don't wait more than 250ms
{
  try
  {
    //do something
  }
  finally
  {
    Monitor.Exit(objectLock);
  }
}
else
{
  //fallback code
}

还值得查看TryEnter()的重载以及其他同步对象,例如ReaderWriterLockSlim