我实现了一个泛型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)
{
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);
}
}用法
try
{
service = myPool.Get();
}
finally
{
if (service != null)
myPool.Put(service);
}发布于 2011-02-24 00:09:21
死锁可能是由stack.Count > 0引起的。这意味着你有一个等待/脉冲问题。总是在Push()之后调用Pulse并不是一个坏主意。或者至少在Count <5左右的时候。请记住,等待/脉冲机制没有内存。
一个场景:
Wait线程A尝试从空池中获取,并执行
()
线程B尝试从空池中获取,并执行Wait()
线程C放入池中,执行Pulse()
线程D放回到池中并且不脉冲(计数== 2)
线程A被激活并获得它的项。
线程B处于等待状态。恢复的希望很小。
发布于 2011-02-24 00:05:41
我现在看得更清楚了。我必须有一个读卡器锁,对吗?
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();
}
}
}发布于 2011-02-24 00:38:57
只是猜测,但如果删除"stack.Count == 1“条件并始终在Put函数中发出脉冲呢?也许两个Puts正被快速地按顺序调用,而只有一个等待线程被唤醒。
https://stackoverflow.com/questions/5093294
复制相似问题