lock()语句会阻塞进程/ appdomain中的所有线程吗?

Mik*_*keJ 11 c# asp.net multithreading

也许问题听起来很愚蠢,但我不明白'关于线程和锁定的东西,我想得到一个确认(这就是我问的原因).

所以,如果我有10个服务器,同时有10个请求来到每个服务器,那就是整个服务器场的100个请求.没有锁定,那就是100请求数据库.

如果我做这样的事情:

private static readonly object myLockHolder = new object();
if (Cache[key] == null)
{
   lock(myLockHolder)
   {
      if (Cache[key] == null)
      {
         Cache[key] = LengthyDatabaseCall();
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

我会做多少个数据库请求?10?100?或者我有线程?

Mar*_*age 11

您有一个对象层次结构:

  • 你有服务器(10)
  • 在每台服务器上,您都有进程(可能只有1个 - 您的服务/应用程序池)
  • 在每个进程中你都有线程(可能很多)

您的代码将禁止同一服务器访问中同一进程内的线程Cache同时修改该对象.您可以跨进程甚至跨服务器创建锁,但随着向上移动层次结构,成本会增加很多.

使用该lock语句实际上并不锁定任何线程.但是,如果一个线程正在锁内执行代码(即在lock语句后面的代码块中),任何其他想要获取锁并执行相同代码的线程必须等到持有锁的第一个线程离开块代码并释放锁.

C#lock语句使用Windows 关键部分,它是一种轻量级锁定机制.如果要锁定进程,可以使用互斥锁.要跨服务器锁定,您可以使用数据库或共享文件.

正如dkackman所指出的,.NET具有AppDomain的概念,这是一种轻量级进程.每个进程可以有多个AppDomain.C#lock语句仅锁定单个AppDomain中的资源,并且层次结构的正确描述将包括进程下方和线程上方的AppDomain.但是,通常在一个进程中只有一个AppDomain,这种区别在某种程度上是无关紧要的.

  • 轻微更正"您的代码将仅禁止同一AppDomain中的线程".C#静态绑定到AppDomain,而不是进程. (3认同)