C# 如何释放一个锁并获取另一个原子
在我的应用程序中,我管理一组锁,我需要这些锁来序列化对某些对象的访问(每个对象都分配了一个锁)。此锁集合(锁管理器)还需要以线程安全的方式进行维护(添加新锁/删除需要序列化的新对象时删除旧锁)。 算法的工作原理如下:C# 如何释放一个锁并获取另一个原子,c#,.net,multithreading,C#,.net,Multithreading,在我的应用程序中,我管理一组锁,我需要这些锁来序列化对某些对象的访问(每个对象都分配了一个锁)。此锁集合(锁管理器)还需要以线程安全的方式进行维护(添加新锁/删除需要序列化的新对象时删除旧锁)。 算法的工作原理如下: LockManager.Lock(); var myLock = LockManager.FindLock(myObject); LockManager.Unlock(); // atomic myLock.Lock();
LockManager.Lock();
var myLock = LockManager.FindLock(myObject);
LockManager.Unlock(); // atomic
myLock.Lock(); // atomic
while (!LockManager.TryEnterIndividualLock(myObject))
{
// Do something else until the lock can be entered.
}
交换两行不是一个好的解决方案。如果锁定myLock
会被阻止,那么这也会阻止解锁LockManager
请求其他锁来阻止
我需要的是两个标记行是原子执行的。有没有办法做到这一点?所以您想:
- 确保已输入单个锁(通过
)myLock
- 然后解锁锁管理器
- 使上述两个操作原子化
- 如果无法立即进入单个锁,则不允许此新的原子操作阻止
TryXXX
方法中,您经常可以看到这一点。您只需在myLock
类型上定义一个TryLock
。然后,LockManager
可以如下所示
public class LockManager
{
public bool TryEnterIndividualLock(object value)
{
Lock();
try
{
var myLock = FindLock(value);
if (myLock != null)
{
return myLock.TryLock();
}
return false;
}
finally
{
Unlock();
}
}
}
然后调用代码将如下所示:
LockManager.Lock();
var myLock = LockManager.FindLock(myObject);
LockManager.Unlock(); // atomic
myLock.Lock(); // atomic
while (!LockManager.TryEnterIndividualLock(myObject))
{
// Do something else until the lock can be entered.
}
这会给你想要的原子性,但代价是操作没有成功。如果您希望此操作立即成功,那么您将不得不重新考虑您的总体设计。为什么不在解锁管理器之前先使用锁?为什么不使用另一个锁。makethisactionatomic锁。@CodeInChaos:如果其他锁被阻止,那么第一个锁的释放也会在这段时间内被阻止。@dcarapic您的管理器锁和对象锁应该是独立的,交换最后两行,如果您不能这样做,那么代码中可能有错误。请发布管理器和对象的锁定和解锁代码。@oleksii交换两行不是一个好的解决方案。如果myLock的锁定会被阻止,那么这也会阻止LockManager的解锁,并请求其他锁进行阻止:LockManager.Lock();var myLock=LockManager.FindLock(myObject);myLock.Lock();//如果由于锁已被锁定而被阻止,则LockManager.Unlock();//那么这个也会被封锁