问题是我一直在使用lock语句来保护我的代码的关键部分,但是现在,我意识到我可以允许并发执行那些关键代码是满足某些条件的.
有没有办法调节锁?
我认为那个问题叫"竞争条件!".如果在检查后不久条件从true变为false,但在线程进入代码的关键部分之前怎么办?或者一个线程正在执行它?
我不是线程专家,但听起来你可能正在寻找这样的东西(双重检查锁定).想法是在获得锁之前和之后检查条件.
private static object lockHolder = new object(); if (ActionIsValid()) { lock(lockHolder) { if (ActionIsValid()) { DoSomething(); } } }
bool locked = false; if (condition) { Monitor.Enter(lockObject); locked = true; } try { // possibly critical section } finally { if (locked) Monitor.Exit(lockObject); }
编辑:是的,有一个竞争条件,除非您可以确保在线程进入时条件是恒定的.
Action doThatThing = someMethod; if (condition) { lock(thatThing) { doThatThing(); } } else { doThatThing(); }
实际上,为了避免出现竞争状况,我很想在ReaderWriterLockSlim
这里使用-将并发访问视为读锁定,而将独占访问视为写锁定。这样,如果条件发生变化,您将不会最终在该区域盲目执行某些不适当的代码(错误地认为它是安全的);有点冗长,但是(格式化为空格):
if (someCondition) { lockObj.EnterReadLock(); try { Foo(); } finally { lockObj.ExitReadLock(); } } else { lockObj.EnterWriteLock(); try { Foo(); } finally { lockObj.ExitWriteLock(); } }