Kir*_*ril 20 .net c# concurrency multithreading deadlock
我已经编写了一个测试,我认为应该是一个有效的死锁案例.看来,一旦lock已经被一个类的实例获取,该实例就不再需要重新获取lock,即使我明确地尝试再次调用另一个方法lock.
这是班级:
internal class Tester
{
private readonly object _sync = new object();
public Tester() { }
public void TestLock()
{
lock (_sync)
{
for (int i = 0; i < 10; i++)
{
Deadlock(i);
}
}
}
private void Deadlock(int i)
{
lock (_sync)
{
Trace.WriteLine(i + " no deadlock!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
0没有死锁!
1没有死锁!
2没有死锁!
3没有死锁!
4没有死锁!
5没有死锁!
6没有死锁!
7没有死锁!
8没有死锁!
9没有死锁!
我本以为这会导致僵局......任何人都能对此有所了解吗?
Mar*_*ell 42
.NET中的锁是可重入的.仅阻止来自其他线程的收购.当同一个线程多次锁定同一个对象时,它只是增加一个计数器,并在释放时减少它.当计数器达到零时,锁实际上被释放以便从其他线程访问.
Han*_*ant 13
Monitor,Mutex和ReaderWriterLock类维护具有线程关联的锁.ReaderWriterLockSlim类允许您选择,它具有一个采用LockRecursionPolicy值的构造函数.使用LockRecursionPolicy.NoRecursion是一种优化,如果你的锁定非常精细,那么这是一个相当大的优化.
Semaphore类是一个没有任何线程关联的同步类.此代码可靠地死锁:
class Tester {
private Semaphore sem = new Semaphore(1, 1);
public void TestLock() {
sem.WaitOne();
for (int i = 0; i < 10; i++) Deadlock(i);
sem.Release();
}
private void Deadlock(int i) {
if (!sem.WaitOne(100)) Console.WriteLine("deadlock!");
else {
sem.Release();
Console.WriteLine("No deadlock!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
通常,线程仿射同步类需要两个线程和两个锁死锁.标准模式是一个线程获取锁A和B,另一个线程获取B和A.顺序很重要.
.NET编程中存在不太明显的死锁情况,这是由锁无法看到的,因为它们内置于.NET框架代码中.一个非常经典的是BackgroundWorker.您可以在Busy属性上旋转的UI线程中编写代码,等待BGW完成.当BGW具有RunWorkerCompleted事件处理程序时,它总是会死锁.它在UI线程空闲之前无法运行,在事件处理程序完成运行之前,BGW的Busy属性不会为false.