也许这个问题听起来很愚蠢,但我不明白“关于线程和锁定的一些事情,我想得到确认(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/