当前位置: 首页 > 编程语言 > C#

如何两处加锁,一处释放?Share

时间:2023-04-11 03:41:06 C#

如何实现两处加锁,一处释放?我是c#的新手。我需要用两种方法获取锁,但用一种方法释放它。那行得通吗?publicvoidobtainLock(){Monitor.Enter(lockObj);}publicvoidobtainReleaseLock(){lock(lockObj){doStuff}}具体可以先调用obtainLock再调用obtainReleaseLock吗?C#中是否允许“doubleLock”?这两种方法总是从同一个线程调用,但在另一个线程中使用lockObj进行同步。更新:在所有评论之后,您如何看待这样的代码?这是理想的吗?publicvoidobtainLock(){if(needCallMonitorExit==false){Monitor.Enter(lockObj);needCallMonitorExit=true;}//doStuff}publicvoidobtainReleaseLock(){try{lock(lockObj){//doAnotherStuff}}finally{if(needCallMonitorExit==true){needCallMonitorExit=false;Monitor.Exit(lockObj);}}}是的,锁是“可重入的”,因此调用可以“双重锁定”(你的短语)lockObj。但请注意,它需要完整的发布计数;您需要确保有一个对应的“ReleaseLock”来匹配“ObtainLock”。但是,我建议让调用者lock(...)您公开的某些属性更容易:publicobjectSyncLock{get{returnlockObj;现在调用者可以(而不是obtainLock()):lock(something.SyncLock){//...}更容易正确。因为这是内部使用的相同底层lockObj,所以即使在锁定SyncLock代码中使用了obtainReleaseLock(等),它也会与任一用法同步。随着上下文更清晰(注释),Wait和Pulse似乎可以这样做://^^^这个***释放了***锁(无论需要多少次),并且//进入等待队列;当*另一个*线程“发出脉冲”时,它//进入就绪队列;当锁*可用*时,它//重新获取锁(回到它持有它的次数//之前)并恢复工作}//做一些工作,很高兴发生了一些特别的事情,并且//我们有lock}}voidSomeMethodThatMightSignalSomethingSpecial(){lock(lockObj){//做一些事情Monitor.PulseAll(lockObj);//^^^这会将**所有**项目从待定队列移动到就绪队列//注意还有Pulse(...)移动*单个*项目}}注意Wait你可以想要使用接受超时的重载,以避免永远等待;请注意,必须循环并重新验证是很常见的,例如:lock(lockObj){while(needSomethingSpecialToHappen){Monitor.Wait(lockObj);//在这一点上,我们知道我们被脉冲了,但也许另一个等待//线程抢在我们前面!重新检查条件,然后继续;这可能//也是检查某些“中止”条件的好地方(并且//记得在中止时执行PulseAll())}//做一些工作,很高兴发生了一些特别的事情,我们有锁}您必须使用Monitor来实现此功能请注意,如果您不小心将它们锁定并取出并在单独的代码区域中释放它们,则可能会造成危险,然后您可能会遇到死锁和竞争条件Monitor.Exit(lockObj);在给定时间只有一个所有者可以持有锁;这是独家的。虽然锁可以被锁定,但更重要的组件是确保它们被获取和释放适当的次数,从而避免难以诊断的线程问题。当您通过lock{...}包装代码时,您实际上是在进入和离开范围时调用Monitor.Enter和Monitor.Exit。当您显式调用Monitor.Enter时,您将获得锁,此时您需要调用Monitor.Exit来释放锁。这是行不通的。代码lock(lockObj){//dostuff}被翻译成类似Monitor.Enter(lockObj)try{//dostuff}finally{Monitor.Exit(lockObj)}这意味着你的代码进入锁两次但只释放一次。根据文档,如果在调用Exit时经常调用Lock,那么锁只会被线程释放,而你的代码中不是这样的。摘要:您的代码在调用obtainReleaseLock时不会死锁,但线程永远不会释放lockObj上的锁。您需要显式调用Monitor.Exit(lockObj),因此对Monitor.Enter的调用与对Monitor.Exit的调用次数相匹配。以上就是C#学习教程:如何两处获得锁,一处释放?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: