我有 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;
}
}
监视器是重入的,因此您可以多次获取它们。但是,您必须记住按相同的数字释放它们,否则它们将保持锁定状态。