简体   繁体   中英

Lock not being released for other threads

I have 5 threads which try to enter a critical section of a static class at a random time. If another thread is in the critical section i want the others to 'back-off' and try at a later time. The problem is that it seems that the lock is not being released after the first thread enters the critical section because for the others false will always be returned if i 'breakpoint' at Monitor.TryEnter(thisLock) . Any help would be appreciated. Thanks.

This is my code:

static class Receiver
    {
        public static object thisLock = new object();
        public static int success;

        public static bool hasLocked()
        {
            if(Monitor.TryEnter(thisLock))
            {
                Monitor.Enter(thisLock);
                System.Threading.Thread.Sleep(10);
                success++;
                Monitor.Exit(thisLock);
                return true;
            }
            return false;
        }
    }

It is legal for the same thread to invoke Enter more than once without it blocking; however, an equal number of Exit calls must be invoked before other threads waiting on the object will unblock.

http://msdn.microsoft.com/en-us/library/de0542zz%28v=vs.110%29.aspx

Basically, you're acquiring the lock two times in your code. You need to remove the call to Monitor.Enter since Monitor.TryEnter already acquired the lock.

static class Receiver
{
    public static object thisLock = new object();
    public static int success;

    public static bool hasLocked()
    {
        if(Monitor.TryEnter(thisLock))
        {
            System.Threading.Thread.Sleep(10);
            success++;
            Monitor.Exit(thisLock);

            return true;
        }

        return false;
    }
}

You're acquiring the locks twice, but only releasing it once.

If TryEnter succeeds then you will have acquired the lock. This means you don't need to explicitly acquire it again. However, you do need to release it explicitly. So your code should look like this:

static class Receiver
    {
        public static object thisLock = new object();
        public static int success;

        public static bool hasLocked()
        {
            if(Monitor.TryEnter(thisLock))
            {
                System.Threading.Thread.Sleep(10);
                success++;
                Monitor.Exit(thisLock);
                return true;
            }
            return false;
        }
    }

Monitors are reenterant, so you can acquire them multiple times. However, you must remember to release them by the same number, otherwise they will stay locked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM