首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于锁对象和子类的问题

关于锁对象和子类的问题
EN

Stack Overflow用户
提问于 2010-06-29 16:49:34
回答 5查看 1.4K关注 0票数 2

因此,我有一个基类,它有一个私有锁定对象,如下所示:

代码语言:javascript
复制
class A
{
    private object mLock = new object();

    public virtual void myMethod()
    {
        lock(mLock)
        {
            // CS
        }
    }
}

这个锁定对象用于A的大多数操作.因为它们需要线程安全。

现在,假设我是这样从A继承的:

代码语言:javascript
复制
class B : public A
{
    public override void myMethod()
    {
        lock(???)
        {
            // CS of mymethod here

            // Call base (thread safe alread)
            base.myMethod();
        }
    }
}

使B线程安全的约定是什么?B是否也应该像A那样拥有一个私有锁定对象?如果我需要像上面那样调用基本方法呢?

我想我只是好奇在基类已经线程安全的情况下,使子类线程安全的约定是什么。谢谢!

编辑:有些人问我所谓的“线程安全”是什么意思.我要澄清的是,我试图通过互斥来实现线程安全.一次只应该执行一个线程,这可能会改变对象的状态。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-06-29 16:54:08

您可能会公开A使用的锁:

代码语言:javascript
复制
protected object SyncLock { get { return mLock; } }

如果B有自己的锁对象,则很容易得到以下结果:

  • 正在使用不同的锁,可能会导致争用条件。(如果保持锁B时发生的操作与保持锁A时发生的操作是正交的,那么就可以了。)
  • 锁按不同的顺序递归取出,从而导致死锁。(同样,正交参数也适用。)

由于锁在.NET中是递归的(无论是好的还是坏的),如果您的重写锁与A的实现相同,那么调用base.myMethod并递归地获取/释放锁是很好的。

说了这些之后,我渴望使大多数类非线程安全或不可变(只有与线程有关的类需要线程知识),而且大多数类不需要为继承而设计。

票数 4
EN

Stack Overflow用户

发布于 2010-06-29 16:55:08

这要看情况了。如果您的子类只使用来自基类的安全方法,并且没有添加任何额外的不安全状态,那么您就不必做任何事情(首选)。如果它添加了一些与基类状态无关的额外状态,那么您可以在子类中创建一个单独的锁对象并使用它。另一方面,如果需要确保以某种“事务性”方式更改基类中的新状态和状态,那么我将保护基类中的lock对象并使用它。

票数 4
EN

Stack Overflow用户

发布于 2010-06-29 16:59:45

没有足够的信息来回答你的问题,但首先要做的是。

仅使用lock 块并不能使代码线程安全.

您在A中所做的一切就是让一个以上的线程一次不可能调用包含在lock(mLock)中的任何函数。线程安全是一个宽泛的术语,防止并发调用只是一个方面(并不总是您想要或需要的)。如果这是你所需要的,那么你显然已经采取了正确的方法。确定一下就行。

第二,您需要向子类公开的内容在上面的代码中并不明显。有三种情况:

  1. B可能会调用protected (或者,如果它与A位于同一个程序集中),则在A上调用不包含在lock(mLock)中的函数,blocks
  2. B只调用包含在lock(mLock)块中的A函数,并且不提供任何需要您阻止并发calls
  3. B的操作,只调用包含在lock(mLock)块中的A上的函数,并且提供自己的操作,这些操作要求您防止并发调用。H 227G 228

这实际上归结为两个不相关的问题:

protected)?

  • Will

  • B将以一种需要保护的方式与A交互(换句话说,以一种已经不是A的方式公开需要保护的功能,如果是的话,它们应该使用相同的锁定对象吗?

)

如果1) true of 2)是true,并且它们应该使用相同的锁定对象,那么您将需要通过protected属性公开锁定对象,并在所有锁中使用它(我建议在A中也使用它以提高可读性)。

如果两者都不是真的,那就别担心。如果2)为真,但它们不需要使用相同的锁定对象(换句话说,对AB进行并发调用是可以接受的),那么不必担心公开锁定对象。请记住,BA上受lock(mLock)保护的函数进行的任何调用都会锁定该对象,而不管外部锁是什么。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3142850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档