在我的应用程序中,我管理了一系列锁,我需要序列化对某些对象的访问(每个对象都分配了一个锁)。这个锁(锁管理器)集合也需要以线程安全的方式进行维护(添加新锁/删除旧锁,因为需要序列化的新对象被添加/删除)。 该算法的工作原理如下:
LockManager.Lock();
var myLock = LockManager.FindLock(myObject);
LockManager.Unlock(); // atomic
myLock.Lock(); // atomic
交换两行不是一个好方法。如果锁定myLock
会阻止,那么这也会阻止LockManager
解锁,从而阻止其他锁的请求。
我需要的是两条标记的行以原子方式执行。有没有办法实现这个目标?
答案 0 :(得分:3)
所以你想:
myLock
)LockManager
类似于你不能绕过物理定律来创造一个永动机,你也无法通过原子方式执行一系列操作来规避计算定律,即使它的一个成分能够阻止它,事实上,有望阻止。换句话说,在各个部分也完成之前,无法完成操作。
然而,我们所能做的就是以一种全有或全无的方式尝试这种原子操作,只要我们对“无”结果没问题,就永远不会阻止。使用许多并发数据结构中存在的TryXXX
方法,您会看到很多。您需要做的就是在TryLock
类型上定义myLock
。然后,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();
}
}
}
然后调用代码如下所示:
while (!LockManager.TryEnterIndividualLock(myObject))
{
// Do something else until the lock can be entered.
}
这将为您提供您正在寻找的原子性,但代价是操作没有成功。如果您依靠此操作立即成功,那么您将不得不重新考虑您的整体设计。