假设我有以下课程:
public class IntBagWithLock
{
private readonly lockObject = new object();
private bool assigned = false;
private int data1;
private int data2;
public int? Data1
{
get { lock (lockObject) { return assigned ? data1 : (int?)null; } }
}
public int? Data2
{
get { lock (lockObject) { return assigned ? data2 : (int?)null; } }
}
public bool Assigned { get { lock(lockObject) { return assigned; } }
public bool TrySetData(int value1, int value2)
{
lock (lockObject)
{
if (assigned) return false;
data1 = value1;
data2 = value2;
assigned = true;
return true;
}
}
public bool IsEquivalentTo(IntBagWithLock other)
{
if (ReferenceEquals(this, other)) return true;
if (ReferenceEquals(other, null)) return false;
lock (lockObject)
{
if (!assigned) return false;
lock (other.lockObject)
{
return other.assigned && other.data1 == data1 && other.data2 == data2;
}
}
}
}
我在这里担心的问题是,由于实现的方式,如果一个线程调用并获取了锁,而另一个调用并获取了锁IsEquivalentTo
,我可能会陷入死锁状态。item1.IsEquivalentTo(item2)
item1
item2.IsEquivalentTo(item1)
item2
我应该怎么做才能尽可能确保不会发生这种死锁?
更新 2:代码示例已被修改为更接近我实际拥有的。我认为所有答案仍然有效。