首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对SyncRoot模式的一些澄清:使用此模式的正确方法是什么?

对SyncRoot模式的一些澄清:使用此模式的正确方法是什么?
EN

Stack Overflow用户
提问于 2012-09-14 12:53:15
回答 2查看 3.4K关注 0票数 8

为了避免死锁,我阅读了一些关于SyncRoot模式的一般规则。阅读几年前的一个问题(请参阅这个链接),我想我理解这种模式的某些用法可能是不正确的。特别是,我集中讨论了本题中的下列句子:

您将注意到SyncRoot属性在System.Collections中的许多集合上。回顾一下,我认为这个财产是个错误..。请放心,在构建这些集合的通用版本时,我们不会犯同样的错误。

实际上,例如,List<T>类没有实现SyncRoot属性,或者更正确地说,它是显式实现的(参见这个答案),因此您必须转换为ICollection才能使用它。但这句话认为,公开私有SyncRoot字段与锁定this (参见这个答案)一样糟糕,这一点在这句话中也得到了证实。

因此,如果我正确理解,当我实现一个非线程安全的数据结构时,由于它可以在多线程上下文中使用,我不应该(实际上,我不能)提供SyncRoot属性。但是,我应该让开发人员(将使用此数据结构)承担将其与私有SyncRoot对象关联的任务,如下面的示例代码所示。

代码语言:javascript
复制
public class A
{
    private MyNonThreadSafeDataStructure list;
    private readonly object list_SyncRoot = new object;

    public Method1()
    {
        lock(list_SyncRoot)
        {
            // access to "list" private field
        }
    }

    public Method2()
    {
        lock(list_SyncRoot)
        {
            // access to "list" private field
        }
    }
}

总之,我理解同步/锁定的最佳实践应该如下:

  1. 任何私有SyncRoot对象都不应通过公共属性公开;换句话说,自定义数据结构不应提供公共SyncRoot属性(也请参见这句话)。
  2. 通常,使用私有对象进行锁定并不是强制性的(请参阅这个答案)。
  3. 如果一个类有多组操作需要同步,而不是彼此同步,那么它应该有多个私有SyncRoot对象(参见这句话)。

上面写的是这个模式的正确用法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-14 13:52:49

我将避免将SyncRoot属性添加到我设计的类型中,原因如下:

  • 我的类型的用户可能需要使用不同的同步机制,例如MutexReaderWriterLockReaderWriterLockSlim等。
  • 这种类型变得更胖:它的责任变得更加分散。为什么我要添加对显式多线程锁定的支持,而不支持其他触发器呢?我会强迫用户只进行一次练习,这可能不是所有情况下最好的解决方案。
  • 我需要正确地实现该属性(不返回thistypeof(MyClass)),即这是错误的: 公共对象SyncRoot {get {返回此;}

我还将避免从SyncRoot框架类型中使用.NET属性。如果我需要创建一个w/o SyncRoot属性线程安全类型,我将使用一个锁定模式,如果一个类型具有此属性,我仍然不会选择锁定SyncRoot。这使我的代码风格一致,易于阅读/维护。

票数 4
EN

Stack Overflow用户

发布于 2012-09-14 13:33:31

这里有许多概念。首先,正确实现的是一个线程安全类,该类的使用者不需要自己进行同步。因此,绝对不需要公开syncRoot对象。在旧集合类中,由于类不是线程安全的,所以公开了SyncRoot属性。

在锁定任意对象并锁定内部集合时,程序的正确性或性能绝对没有差别。只要对两者的引用没有改变,它们的工作原理就像参数一样适用于Monitor.Enter/Exit。你的内心收藏会改变吗?如果没有,也把它标记为只读。

第三,对基于不同操作的不同锁的使用提出了意见。典型的例子是ReaderWriterLock。您应该根据类公开的不同功能来分析使用不同级别锁的需要。

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

https://stackoverflow.com/questions/12424993

复制
相关文章

相似问题

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