Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对象池实现死锁_C#_Multithreading_Monitor - Fatal编程技术网

C# 对象池实现死锁

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) {

我已经实现了一个通用的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); 
        }
    }

我现在看得更清楚了一点。我必须有一个读卡器锁,对吗

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)