所以,我有一个基类,它有一个像这样的私有(private)锁定对象:
class A
{
private object mLock = new object();
public virtual void myMethod()
{
lock(mLock)
{
// CS
}
}
}
此锁定对象用于 A
的大部分操作...因为它们需要线程安全。
现在,假设我继承自 A
,如下所示:
class B : public A
{
public override void myMethod()
{
lock(???)
{
// CS of mymethod here
// Call base (thread safe alread)
base.myMethod();
}
}
}
使 B
线程安全的约定是什么? B
是否也应该像 A
一样有一个私有(private)锁定对象?如果我需要像上面那样调用基本方法怎么办?
我想我只是好奇当基类已经是线程安全的时候,让子类线程安全的约定是什么。谢谢!
编辑:有些人问我所说的“线程安全”是什么意思……我会通过补充说明来澄清,我正在尝试通过互斥来实现线程安全……只有一个线程一次应该执行可能改变对象状态的代码。
最佳答案
您可能会公开 A 使用的锁:
protected object SyncLock { get { return mLock; } }
如果 B 有自己的锁对象,你很容易得到:
- 使用了不同的锁,可能会导致竞争条件。 (这可能没问题 - 如果在持有锁 B 时发生的操作与持有锁 A 时发生的操作正交,您可能会侥幸逃脱。)
- 以不同的顺序递归地取出锁,导致死锁。 (同样,正交性论点适用。)
由于锁在 .NET 中是递归的(无论好坏),如果您的覆盖锁定与 A 的实现相同的对象,则可以调用 base.myMethod
并递归获取/释放锁.
综上所述,我热衷于使大多数类成为非线程安全的或不可变的(只有与线程相关的类才需要线程知识)和大多数不需要为继承 IMO 设计类。
关于c# - 关于锁对象和子类的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3142850/