字典作为线程安全变量 [英] Dictionary as thread-safe variable

查看:139
本文介绍了字典作为线程安全变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类(单),它包含一个静态字典

 私有静态字典<字符串,RepositoryServiceProvider> repositoryServices = NULL; 

在此I类填充字典的实例(可以从多个线程发生)。起初我刚

  RepositoryServiceProvider服务= NULL; 
repositoryServices.TryGetValue(this.Server.Name,停止服务);
如果(服务== NULL){
服务=新RepositoryServiceProvider(this.Server);
repositoryServices.Add(this.Server.Name,服务);
}



后来我已经添加了一些例外的项目,所以我把它改为:

  RepositoryServiceProvider服务= NULL; 
repositoryServices.TryGetValue(this.Server.Name,停止服务);
如果(服务== NULL){
锁(锁){
repositoryServices.TryGetValue(this.Server.Name,停止服务);
如果(服务== NULL){
服务=新RepositoryServiceProvider(this.Server);
repositoryServices.Add(this.Server.Name,服务);
}
}
}

和挂锁在类

 私有静态只读对象挂锁=新的对象(); 



这是线程安全的?或它过于复杂?或者我应该使用 ConcurentDictionary


< DIV CLASS =h2_lin>解决方案

如果你可以使用的 ConcurrentDictionary - 这是在几种情况下比你更快的方法,因为它实现了大部分的操作锁定自由而被线程安全的。



编辑 - 按评论:



大多数的操作锁定自由这个词有点太笼统...



基本上这意味着减少争......因此,在某些情况下,当第一桶被锁定的作品好像有更高的效率相比,有一个全局锁,即访问第二桶的情况没有来自访问代码的POV锁...虽然这意味着锁定本地到桶...在实际应用中它提供了比一个全局锁好得多的性能 - 电除尘器。多核


I have a class (singleton) and it contains a static Dictionary

private static Dictionary<string, RepositoryServiceProvider> repositoryServices = null;

in the instance of this class I populate the dictionary (can occur from multiple threads). At first I had just

        RepositoryServiceProvider service = null; 
        repositoryServices.TryGetValue(this.Server.Name, out service);
        if (service == null) {
          service = new RepositoryServiceProvider(this.Server);
          repositoryServices.Add(this.Server.Name, service);  
        }

then I got some exceptions as Item already added so I changed it to:

        RepositoryServiceProvider service = null;    
        repositoryServices.TryGetValue(this.Server.Name, out service);
        if (service == null) {
          lock (padlock) {
            repositoryServices.TryGetValue(this.Server.Name, out service);
            if (service == null) {
              service = new RepositoryServiceProvider(this.Server);
              repositoryServices.Add(this.Server.Name, service);  
            }
          }
        }

and padlock is in the class:

private static readonly object padlock = new object();

is this thread safe? or its overcomplicated? or should I use ConcurentDictionary?

解决方案

IF you can use ConcurrentDictionary - it is in several situations faster than your approach because it implements most operations lock-free while being thread-safe.

EDIT - as per comments:

The term "most operations lock-free" is a bit too general...

Basically it means reduced contention ... thus in some cases more efficiency compared to a situation with one global lock, i.e. accessing a second bucket while the first bucket is locked works as if there was no lock from the POV of the accessing code... although that means a lock local to that bucket... in real-world applications it delivers much better performance than a global lock - esp. with multi-core.

这篇关于字典作为线程安全变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆