次のクラスがあるとします。
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 : コード サンプルは、私が実際に持っているものに近づくように変更されました。すべての答えはまだ有効だと思います。