我看到下面的代码,我想用它来做一个简单的活动,这个活动一次只能执行一次,并且不会经常发生(因此一次发生两次的机会非常小,但你永远不知道).
所以代码:
// class variable
private static object syncRoot = new object();
// in a method:
lock (syncRoot)
{
DoIt();
}
Run Code Online (Sandbox Code Playgroud)
当另一个线程来到并想要执行代码时,它会等到锁被释放多长时间?永远,或者你可以以某种方式设置超时?
第二个:如果DoIt()方法抛出异常,锁是否仍然被释放?
jas*_*son 76
当另一个线程来到并想要执行代码时,它会等到锁被释放多长时间?
lock 将阻止尝试无限期进入锁的线程,直到被锁定的对象被释放.
你能以某种方式弄湿超时吗?
如果需要指定超时,请使用Monitor.TryEnterin
if(Monitor.TryEnter(obj, new TimeSpan(0, 0, 1))) {
try {
body
}
finally {
Monitor.Exit(obj);
}
}
Run Code Online (Sandbox Code Playgroud)
如果DoIt()方法抛出异常,锁是否仍然被释放?
是的,a DoIt()被翻译成
bool lockWasTaken = false;
var temp = obj;
try { Monitor.Enter(temp, ref lockWasTaken); { body } }
finally { if (lockWasTaken) Monitor.Exit(temp); }
Run Code Online (Sandbox Code Playgroud)
有关抛出异常时可能发生的事情的详细信息,请参阅锁定和异常不混合.
Mar*_*ell 33
如前所述,常规锁将永远等待,这是一个死锁的风险.
首选机制是(并注意到ref):
bool lockTaken = false;
try {
Monitor.TryEnter(lockObj, timeout, ref lockTaken);
if(!lockTaken) throw new TimeoutException(); // or compensate
// work here...
} finally {
if(lockTaken) Monitor.Exit(lockObj);
}
Run Code Online (Sandbox Code Playgroud)
这避免了在某些边缘情况下不释放锁的风险.
的finally(其存在于任何合理的实现),确保锁即使在错误条件释放.
一个简单的lock(syncRoot)将永远等待.
你可以用它替换它
if (System.Threading.Monitor.TryEnter(syncRoot, 1000))
{
try
{
DoIt();
}
finally
{
System.Threading.Monitor.Exit(syncRoot);
}
}
Run Code Online (Sandbox Code Playgroud)
每个线程都应该确保异常安全锁定.
请注意,标准lock(syncRoot) {}被重写为Monitor.Enter(syncRoot)try/finally
| 归档时间: |
|
| 查看次数: |
37676 次 |
| 最近记录: |