未为其他线程释放锁

本文关键字:释放 线程 其他 | 更新日期: 2023-09-27 18:34:41

我有 5 个线程尝试随机进入静态类的关键部分。如果另一个线程在关键部分,我希望其他线程"退避"并在以后尝试。问题是,在第一个线程进入关键部分后,锁似乎没有被释放,因为对于其他线程,如果我在Monitor.TryEnter(thisLock)"断点",将始终返回 false。任何帮助将不胜感激。谢谢。

这是我的代码:

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

未为其他线程释放锁

同一线程多次调用 Enter 而不阻塞是合法的;但是,在等待对象的其他线程取消阻塞之前,必须调用相同数量的 Exit 调用。

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

基本上,您在代码中获取了两次锁。您需要删除对Monitor.Enter的调用,因为Monitor.TryEnter已经获得了锁。

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

您获取了两次锁,但只释放了一次。

如果TryEnter成功,那么您将获得锁。这意味着您无需再次显式获取它。但是,您确实需要显式释放它。所以你的代码应该看起来像这样:

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

监视器是重入的,因此您可以多次获取它们。但是,您必须记住按相同的数字释放它们,否则它们将保持锁定状态。