【问题标题】:How can I make private static field of the static class thread safe?如何使静态类线程的私有静态字段安全?
【发布时间】:2010-12-21 16:25:36
【问题描述】:

我有一个静态类,它有一个私有字典。我已经编写了公共方法来添加和删除对象。现在我想确保当我从字典中删除其中一项时,没有其他人在使用它。

我怎样才能做到这一点?

【问题讨论】:

    标签: c# static thread-safety


    【解决方案1】:

    您的意思是要确保没有其他人在使用 字典,或者没有其他人在使用 字典中的值?

    您可以使用锁定来解决第一个问题……但您不能真正解决第二个问题。有人可以从字典中获取对该对象的引用,并尽可能长时间地存储该引用。如果值是接口类型,可能有一个解决方案 - 您可以通过额外的“包装器”类委托所有调用,并使该包装器类无效。如果您愿意,我可以详细介绍,但我希望您真的只对第一种安全类型感兴趣 :)

    可以这样实现:

    private static readonly object mutex = new object();
    
    // Or whatever
    private static readonly Dictionary<string, string> map =
        new Dictionary<string, string>();
    
    public static void AddEntry(string key, string value)
    {
        lock (mutex)
        {
            map[key] = value;
        }
    }
    
    public static string GetValue(string key, string value)
    {
        lock (mutex)
        {
            return map[key];
        }
    }
    

    显然你会想要调整你使用字典的方式。

    如果您使用的是 .NET 4,另一种选择是使用已经是线程安全的 ConcurrentDictionary

    【讨论】:

    • @Jon:有一个问题。我通常将字典本身用作同步根(当它是私有字段时),而不是创建单独的对象。在这种情况下使用单独的对象有什么好处?
    • @Jon:感谢您的回复。我想实现你提到的第二件事。即当我试图从字典中删除它时,确保没有其他人正在使用它。我的应用程序没有使用 .NET 4.0。它在 .NET 3.5 上。但是,您能否提供更多细节来实现它? (你已经提到了包装类)。
    • @jgauffin:我不知道Dictionary 中的代码是否会自行同步。原则上,我几乎总是锁定一个用于在我的班级中锁定的对象。这意味着我永远不必担心 other 代码也会使用该对象进行锁定。
    • @CSharpLearner:这在很大程度上取决于你在谈论什么样的对象,以及你试图禁止什么样的使用。您将无法阻止客户端代码维护您返回的任何引用...但您可能能够使该引用有效地无用。请提供更多详细信息。
    • @CSharpLearner:至少可以说这很棘手 - 而且您很容易最终会长时间阻塞删除线程。如果在删除字典时迭代线程确实继续迭代会导致什么问题?我会尝试重新设计以避免这个问题 - 以目前的形式解决它会很尴尬。
    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 2019-05-21
      • 1970-01-01
      • 2013-05-08
      • 2012-09-22
      • 2015-03-24
      • 2012-03-10
      • 2013-10-09
      • 2011-01-22
      • 2014-09-16
      相关资源
      最近更新 更多