c# - lock() 语句会阻塞进程/应用程序域中的所有线程吗?

标签 c# asp.net multithreading

也许这个问题听起来很愚蠢,但我不明白“关于线程和锁定的一些事情,我想得到确认(here's why I ask)”。

因此,如果我有 10 台服务器并且同时有 10 个请求到达每个服务器,那么整个服务器场就有 100 个请求。如果没有锁定,那就是对数据库的 100 个请求。

如果我这样做:

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

我将执行多少数据库请求? 10? 100?还是和我有线程一样多?

最佳答案

你有一个对象层次结构:

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

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

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

C# lock 语句使用 Windows critical section这是一个轻量级的锁定机制。如果你想跨进程锁定,你可以使用 mutex反而。要跨服务器锁定,您可以使用数据库或共享文件。

正如 dkackman 指出的那样,.NET 具有 AppDomain 的概念,它是一种轻量级进程。每个进程可以有多个 AppDomain。 C# lock 语句仅锁定单个 AppDomain 中的资源,对层次结构的适当描述将包括进程下方和线程上方的 AppDomain。但是,通常您在一个进程中只有一个 AppDomain,这使得区分有些无关紧要。

关于c# - lock() 语句会阻塞进程/应用程序域中的所有线程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2997438/

相关文章:

asp.net - 在 Azure 上运行由 MySQL 支持的 aspx 站点

multithreading - groovy脚本中的soapui共享数据源

c# - If - else 没有 else 的语句

c# - Asp.Net 核心 WebApi 模型状态不工作

c# - 从集合创建 HashSet<int> 的最坏情况复杂度

c# - 如何取消订阅此 .NET 事件?

ruby - 为什么 Ruby 中对数组的 << 操作不是原子的?

c++ - 如何在 C++ 中创建一个基本线程

C# 在另一个阅读器解决方案中使用阅读器?

c# - 如何在C#中相同命名空间的另一个窗口中编写代码