所以,这不是我的代码,并且已经缩短以显示行为,但它给出了非常意外的结果。
我在一个类中有两个函数和一个锁
object mylock = new object();
List<string> temp = new List<string>();
Func1(string)
{
lock(mylock)
{
temp.Add(string);
}
}
Func2()
{
lock(mylock)
{
temp.ForEach(p => Func1(p));
}
}
现在,我知道这没有意义,但是当调用Func2时,不应该Func1死锁吗?在我们的例子中,它执行。感谢。
答案 0 :(得分:13)
不,它不应该死锁。
Func1
如果被持有锁的人调用(例如Func2
)
“当保持互斥锁定时,在同一执行线程中执行的代码也可以获取并释放锁定。但是,在锁定释放之前,阻止其他线程中执行的代码获取锁定。”
锁定的目标是防止不同的线程访问相同的资源。 Func1
和Func2
位于相同的主题。
答案 1 :(得分:3)
lock
语句(封装Monitor
类)支持在线程内重新进入(递归),即您可以嵌套使用相同监视器的调用。
其他锁定方法:
Monitor
- 支持递归ReaderWriterLock
- 支持递归,但速度很慢ReaderWriterLockSlim
- 支持递归但不鼓励EventHandle
(ManualResetEvent
,AutoResetEvent
,Mutex
,Semaphore
) - 不支持递归答案 2 :(得分:1)
.NET Monitor对象(锁定使用)是递归的,因此持有锁的线程可以自由地再次进入该锁。
(并非所有的锁结构都是递归的,并且可以针对递归支持进行参数化。)