c# – 同时获取多个线程同步锁
我们假设以下代码在我的应用程序中以类似的方式使用:
//------------------------------------- void UseAllResources () { bool bSuccess1 = false; bool bSuccess2 = false; try { bSuccess1 = Monitor::TryEnter (oResource1,msc_iTimeoutMonitor); if (!bSuccess1) return; bSuccess2 = Monitor::TryEnter (oResource2,msc_iTimeoutMonitor); if (!bSuccess2) return; // work on oResource1 and oResource2 } finally { if (bSuccess2) Monitor::Exit (oResource2); if (bSuccess1) Monitor::Exit (oResource1); } } //------------------------------------- void UseResource1 () { bool bSuccess = false; try { bSuccess = Monitor::TryEnter (oResource1,msc_iTimeoutMonitor); if (!bSuccess) return; // work on oResource1 } finally { if (bSuccess) Monitor::Exit (oResource1); } } //------------------------------------- void UseResource2 () { same like UseResource1(),but using oResource2 } 这些函数可能随时被不同的线程调用. 可能会发生这种情况 我宁愿让线程Z失败,如果有的话,因为超时应该是所有锁的整体值. 我可以同时开始获取多个锁吗? 解决方法
解决方案可能是使用ReaderWriterLockSlim类.以下代码在构造函数中包装了一个函数(您要完成的工作).或者,您可以将函数移动到DoWork方法以更改访问资源的方式.
LockedResource implmentation class LockedResource { public delegate void RefAction(); ReaderWriterLockSlim resourceLock; public LockedResource() { //Warning: SupportsRecursion is risky,you should remove support for recursive whenever possible resourceLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); } public bool DoWork(RefAction work,string threadname,int timeout = -1) { try { if (resourceLock.TryEnterWriteLock(timeout)) { if (work != null) { work(); } } else { Console.WriteLine("Lock time out on thread {0}",threadname); } } finally { Console.WriteLine("{0} releasing resource",threadname); if(resourceLock.IsWriteLockHeld) { resourceLock.ExitWriteLock(); } } return false; } } 样本用法 static void Main(string[] args) { object oResouce1 = "-"; object oResouce2 = "-"; LockedResource lock1 = new LockedResource(); LockedResource lock2 = new LockedResource(); //the event wait handles is not required,only used to block thread so that resource values can be printed out at the end of the program var h1 = new EventWaitHandle(false,EventResetMode.ManualReset); var h2 = new EventWaitHandle(false,EventResetMode.ManualReset); var h3 = new EventWaitHandle(false,EventResetMode.ManualReset); WaitHandle[] waitHandles = { h1,h2,h3 }; var t1 = new Thread(() => { lock1.DoWork(() => { oResouce1 = "1"; Console.WriteLine("Resource 1 set to 1"); },"T1"); h1.Set(); }); var t2 = new Thread(() => { lock2.DoWork(() => { oResouce2 = "2"; Console.WriteLine("Resource 2 set to 2"); Thread.Sleep(10000); },"T2"); h2.Set(); }); var t3 = new Thread(() => { lock1.DoWork(() => { lock2.DoWork(() => { oResouce1 = "3"; Console.WriteLine("Resource 1 set to 3"); oResouce2 = "3"; Console.WriteLine("Resource 2 set to 3"); },"T3",1000); h3.Set(); },"T3"); }); t1.Start(); t2.Start(); t3.Start(); WaitHandle.WaitAll(waitHandles); Console.WriteLine("Resource 1 is {0}",oResouce1); Console.WriteLine("Resource 2 is {0}",oResouce2); Console.ReadLine(); } 产量
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |