我看到,对于使用非线程安全的对象,我们用这样的锁包装代码:

private static readonly Object obj = new Object();

lock (obj)
{
    // thread unsafe code
}

那么,当多个线程访问相同的代码时会发生什么(让我们假设它运行在一个ASP。NET web应用程序)。他们排队了吗?如果是的话,他们要等多久?

使用锁对性能有什么影响?


当前回答

不,他们没有排队,他们在睡觉

表单的锁语句

lock (x) ... 

其中x是引用类型的表达式,精确地等价于

var temp = x;
System.Threading.Monitor.Enter(temp); 
try { ... } 
finally { System.Threading.Monitor.Exit(temp); }

你只需要知道它们在等待彼此,只有一个线程会进入锁块,其他线程会等待…

Monitor是完全用。net编写的,所以足够快,还可以查看带有reflector的Monitor类了解更多细节

其他回答

锁将阻止其他线程执行锁块中包含的代码。线程将不得不等待,直到锁块内的线程完成并释放锁。这确实会对多线程环境中的性能产生负面影响。如果您确实需要这样做,您应该确保锁块中的代码可以非常快速地处理。你应该尽量避免昂贵的活动,如访问数据库等。

lock语句被转换为对Monitor的Enter和Exit方法的调用。

lock语句将无限期地等待锁定对象被释放。

不,他们没有排队,他们在睡觉

表单的锁语句

lock (x) ... 

其中x是引用类型的表达式,精确地等价于

var temp = x;
System.Threading.Monitor.Enter(temp); 
try { ... } 
finally { System.Threading.Monitor.Exit(temp); }

你只需要知道它们在等待彼此,只有一个线程会进入锁块,其他线程会等待…

Monitor是完全用。net编写的,所以足够快,还可以查看带有reflector的Monitor类了解更多细节

lock实际上是隐藏的Monitor类。

锁语句中的部分只能由一个线程执行,因此所有其他线程将无限期地等待持有锁的线程完成。这可能导致所谓的死锁。