ObjectPool implementation locks

I implemented the generic ObjectPool class, but experienced that it was once a lock (happens in Monitor.Wait (poolLock))

Can anyone spot an error?

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); 
        }
    }

Using

        try
        {
            service = myPool.Get();
        }
        finally
        {
            if (service != null)
                myPool.Put(service);
        }
+3
source share
4 answers

A dead end probably occurs with stack.Count > 0. This means that you have a problem with Wait / Pulse. It's a good idea to always call Pulse after Push (). Or at least when Count <5 or so. Remember that the Wait / Pulse mechanism has no memory.

Scenario:

Thread A tries to get from an empty pool, and does Wait ()
Thread B tries to get from an empty pool and do Wait ()

C , ()
D Pulse (Count == 2)

.
. .

+3

. , ?

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();
        }
    }
}
0

Just guessing, but what about removing the state of "stack.Count == 1" and always giving an impulse inside the "Put" function? Maybe two Puts are called quickly in sequence, and only one pending thread wakes up.

0
source

Henk answered your question. The following condition is not true:

if (stack.Count == 1)
0
source

Source: https://habr.com/ru/post/1794173/


All Articles