C# 对象池实现死锁
我已经实现了一个通用的ObjectPool类,但它有时会死锁(发生在Monitor.Wait(poolLock))上) 有人能发现错误吗C# 对象池实现死锁,c#,multithreading,monitor,C#,Multithreading,Monitor,我已经实现了一个通用的ObjectPool类,但它有时会死锁(发生在Monitor.Wait(poolLock))上) 有人能发现错误吗 public class ObjectPool<T> where T : new() { private readonly object poolLock = new object(); Stack<T> stack = null; public ObjectPool(int count) {
public class ObjectPool<T> where T : new()
{
private readonly object poolLock = new object();
Stack<T> stack = null;
public ObjectPool(int count)
{
stack = new Stack<T>(count);
for (int i=0; i<count; i++)
stack.Push(new T());
}
public T Get()
{
lock (poolLock)
{
//if no more left wait for one to get Pushed
while (stack.Count < 1)
Monitor.Wait(poolLock);
return stack.Pop();
}
}
public void Put(T item)
{
lock (poolLock)
{
stack.Push(item);
//If adding first send signal
if (stack.Count == 1)
Monitor.Pulse(poolLock);
}
}
我现在看得更清楚了一点。我必须有一个读卡器锁,对吗
public T Get()
{
lock (readerLock)
{
lock (poolLock)
{
//if no more left wait for one to get Pushed
while (stack.Count < 1)
Monitor.Wait(poolLock);
return stack.Pop();
}
}
}
public T Get()
{
锁(读卡器锁)
{
锁(池锁)
{
//如果没有更多的剩余,等待一个被推
while(stack.Count<1)
Monitor.Wait(池锁);
返回stack.Pop();
}
}
}
死锁可能发生在stack.Count>0
上。这意味着你有等待/脉搏问题。总是在推后调用Pulse()不是一个坏主意。或者至少当计数小于5左右时。请记住,等待/脉冲机制没有内存
一个场景:
线程A试图从空的
池,并执行等待()线程B尝试 从空池中获取,并执行 等等 线程C放入池中,执行脉冲() 线程D放回池中并且不脉冲(计数==2) 线程A被激活并获取其项目。
线程B在等待。恢复的希望渺茫
只是一个猜测,但是删除“stack.Count==1”条件并始终在Put函数内部发出脉冲怎么样?可能两个PUT按顺序被快速调用,而只有一个等待的线程被唤醒。Henk回答了您的问题。以下情况不正确:
if (stack.Count == 1)
漂亮的拼图。当它死锁时,是stack.Count==0吗?是Monitor.Wait(poolLock)阻止了它。不,这不会有多大帮助。它在我的integrationtest中有帮助。另外,我想我可以一直监视.Pulse,而不仅仅是当计数为1时。并发性的问题是它很难测试。
if (stack.Count == 1)