登录  /  注册

使用ConcurrentDictionary多线程同步字典集合实例详解

零下一度
发布: 2017-06-24 09:48:24
原创
14021人浏览过

在之前一段时间里面,我的基类多数使用lock和hashtable组合实现多线程内缓存的冲突处理,不过有时候使用这两个搭配并不尽如人意,偶尔还是出现了集合已经加入的异常,对代码做多方的处理后依然如故,最后采用了.net 4.0后才引入的concurrentdictionary多线程同步字典集合,问题顺利解决。

1、使用lock和Hashtable组合实现

在我的基类里面,构建业务对象,一般用BLLFactory.Instance就可以获得对应业务对象的应用了。

var result = BLLFactory<customer>.Instance.FindFirst();
Console.WriteLine(result.ToJson());</customer>
登录后复制

因此使用BLLFactory.Instance这个构建对象后,把它们放到HashTable里面,由于需要设计多线程冲突处理,因此需要使用lock对象来实现锁定的处理。

HashTable表示键/值对的集合。在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key-value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中key-value键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键值对,任何非 null 对象都可以用作键或值。

使用这种方式,偶尔在Web端,还是出现多线程访问冲突的问题,为此我们也可以使用多线程的测试代码来进行测试重现错误,

            try{
                List<thread> list = new List<thread>();for (int i = 0; i {var result = BLLFactory<customer>.Instance.FindFirst();
                        Console.WriteLine(result.ToJson());
                        Console.WriteLine();
                    });

                    list.Add(thread);
                }for (int i = 0; i </customer></thread></thread>
登录后复制

跟踪代码得到错误信息如下所示。

因此,从上面代码可以看到,使用lock(syncRoot)也无法出现的多线程冲突问题。

 

2、使用ConcurrentDictionary替代Hashtable

ConcurrentDictionary是.net4.0推出的一套线程安全集合里的其中一个,和它一起被发行的还有ConcurrentStack,ConcurrentQueue等类型,它们的单线程版本(线程不安全的,Queue,Stack,Dictionary)我们一定不会陌生。ConcurrentDictionaryTKey, TValue> 可由多个线程同时访问,且线程安全,用法同Dictionary很多相同,但是多了一些方法。ConcurrentDictionary 属于System.Collections.Concurrent 命名空间。

System.Collections.Concurrent 命名空间提供多个线程安全集合类。当有多个线程并发访问集合时,应使用这些类代替 System.Collections 和 System.Collections.Generic 命名空间中的对应类型

ConcurrentDictionary这个类提供了下面几个方法,用于对集合的处理

public bool TryAdd(TKey key, TValue value)public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)public TValue this[TKey key] { get; set; }public TValue AddOrUpdate(TKey key, Func<tkey> addValueFactory, Func<tkey> updateValueFactory)    
public TValue AddOrUpdate(TKey key, TValue addValue, Func<tkey> updateValueFactory)public TValue GetOrAdd(TKey key, TValue value)public TValue GetOrAdd(TKey key, Func<tkey> valueFactory)</tkey></tkey></tkey></tkey>
登录后复制

使用ConcurrentDictionary来替代Hashtable,我们来看看BLLFactory的类的实现代码如下所示。

    /// <summary>/// 对业务类进行构造的工厂类/// </summary>/// <typeparam>业务对象类型</typeparam>public class BLLFactory<t> where T : class{//采用ConcurrentDictionary线程安全的集合类来缓存,替代Hashtableprivate static ConcurrentDictionary<string> conCurrentCache = new ConcurrentDictionary<string>(); /// <summary>/// 创建或者从缓存中获取对应业务类的实例/// </summary>public static T Instance
        {get{string CacheKey = typeof(T).FullName;return (T)conCurrentCache.GetOrAdd(CacheKey, s =&gt;{var bll = Reflect<t>.Create(typeof(T).FullName, typeof(T).Assembly.GetName().Name); //反射创建,并缓存return bll;
                });
            }
        }
    }</t></string></string></t>
登录后复制

我们可以看到代码简化了很多,而且使用前面的多线程测试代码,也顺利获取数据,不会出现异常了。

运行代码可以顺利实现,不会出现之前使用Hashtable出现的多线程访问异常了。

以上就是引入ConcurrentDictionary替代Hashtable对多线程的对象缓存处理,能够顺利解决问题的时候,发现其访问效率也是较之前有所提高,一举两得。

 

以上就是使用ConcurrentDictionary多线程同步字典集合实例详解的详细内容,更多请关注php中文网其它相关文章!

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
关于CSS思维导图的课件在哪? 课件
凡人来自于2024-04-16 10:10:18
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号