使用ConcurrentDictionary替代Hashtable对多线程的对象缓存处理
在之前一段时间里面,我的基类多数使用lock和Hashtable组合实现多线程内缓存的冲突处理,不过有时候使用这两个搭配并不尽如人意,偶尔还是出现了集合已经加入的异常,对代码做多方的处理后依然如故,最后采用了.NET 4.0后才引入的ConcurrentDictionary多线程同步字典集合,问题顺利解决。
1、使用lock和Hashtable组合实现
在我的基类里面,构建业务对象,一般用BLLFactory<T>.Instance就可以获得对应业务对象的应用了。
var result = BLLFactory<Customer>.Instance.FindFirst();
Console.WriteLine(result.ToJson());
因此使用BLLFactory<T>.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 = ; i < ; i++)
{
Thread thread = new Thread(() =>
{
var result = BLLFactory<Customer>.Instance.FindFirst();
Console.WriteLine(result.ToJson());
Console.WriteLine();
}); list.Add(thread);
} for (int i = ; i < list.Count; i++)
{
list[i].Start();
}
}
catch(Exception ex)
{
LogTextHelper.Error(ex);
}
跟踪代码得到错误信息如下所示。
因此,从上面代码可以看到,使用lock(syncRoot)也无法出现的多线程冲突问题。
2、使用ConcurrentDictionary替代Hashtable
ConcurrentDictionary是.net4.0推出的一套线程安全集合里的其中一个,和它一起被发行的还有ConcurrentStack,ConcurrentQueue等类型,它们的单线程版本(线程不安全的,Queue,Stack,Dictionary)我们一定不会陌生。ConcurrentDictionary<TKey, 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, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory) public TValue AddOrUpdate(TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory) public TValue GetOrAdd(TKey key, TValue value) public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
使用ConcurrentDictionary来替代Hashtable,我们来看看BLLFactory的类的实现代码如下所示。
/// <summary>
/// 对业务类进行构造的工厂类
/// </summary>
/// <typeparam name="T">业务对象类型</typeparam>
public class BLLFactory<T> where T : class
{
//采用ConcurrentDictionary线程安全的集合类来缓存,替代Hashtable
private static ConcurrentDictionary<string, object> conCurrentCache = new ConcurrentDictionary<string, object>(); /// <summary>
/// 创建或者从缓存中获取对应业务类的实例
/// </summary>
public static T Instance
{
get
{
string CacheKey = typeof(T).FullName; return (T)conCurrentCache.GetOrAdd(CacheKey, s =>
{
var bll = Reflect<T>.Create(typeof(T).FullName, typeof(T).Assembly.GetName().Name); //反射创建,并缓存
return bll;
});
}
}
}
我们可以看到代码简化了很多,而且使用前面的多线程测试代码,也顺利获取数据,不会出现异常了。
运行代码可以顺利实现,不会出现之前使用Hashtable出现的多线程访问异常了。
以上就是引入ConcurrentDictionary替代Hashtable对多线程的对象缓存处理,能够顺利解决问题的时候,发现其访问效率也是较之前有所提高,一举两得。
使用ConcurrentDictionary替代Hashtable对多线程的对象缓存处理的更多相关文章
- ConcurrentHashMap能完全替代HashTable吗?
至此你应该能够明白,ConcurrentHashMap与HashTable都可以用于多线程的环境,但是当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间.因为C ...
- Java多线程基础——对象及变量并发访问
在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...
- 多线程 同步对象 event 简单实例 &进程间通信
多线程 同步对象event import threading,time class Boss(threading.Thread): def run(self): print("BOSS:今晚 ...
- 分布式内存对象缓存系统Memcached-概述
全面掌握Memcached 1. 概述 Memcached是danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,是为了加快网站http://www. ...
- spring ehcache 页面、对象缓存
一.Ehcache基本用法 CacheManager cacheManager = CacheManager.create(); // 或者 cacheManager = CacheManager.g ...
- Ehcache 整合Spring 使用页面、对象缓存
Ehcache 整合Spring 使用页面.对象缓存 Ehcache在很多项目中都出现过,用法也比较简单.一 般的加些配置就可以了,而且Ehcache可以对页面.对象.数据进行缓存,同时支持集群/分布 ...
- (转)Ehcache 整合Spring 使用页面、对象缓存
Ehcache在很多项目中都出现过,用法也比较简单.一般的加些配置就可以了,而且Ehcache可以对页面.对象.数据进行缓存,同时支持集群/分布式缓存.如果整合Spring.Hibernate也非常的 ...
- 缓存插件 EHCache 对象缓存(Spring)
对象缓存就是将查询的数据,添加到缓存中,下次再次查询的时候直接从缓存中获取,而不去数据库中查询. 对象缓存一般是针对方法.类而来的,结合Spring的Aop对象.方法缓存就很简单.这里需要用到切面编程 ...
- 高性能的分布式内存对象缓存系统Memcached
Memcached概述 什么是Memcached? 先看看下面几个概念: Memory:内存存储,不言而喻,速度快,对于内存的要求高,不指出的话所缓存的内容非持久化.对于CPU要求很低,所以常常采 ...
随机推荐
- AOP中的ASPECTJ
一.准备 1.架包 2.配置文件 二.注解的形式 UserDao.java package cn.itcast.spring.aspectj.annocation; public class User ...
- 光场相机重聚焦之三——Matlab光场工具包使用、重聚焦及多视角效果展示
这一小节说一下Matlab光场工具包的使用,展示重聚焦和多视角的效果. 从Lytro illum中导出的raw数据为.lfp格式的光场图像文件(约52M大小),该文件包含以下几部分:光场图像数据raw ...
- SIP DB33标准笔记 监控图像获取
实时监控图像的获取: a) 实时监控图像的获取过程应包括获取实时流.释放实时流.应使用 RFC 3261 中定义的方法INVITE 获取一个摄像机的实时监控视频流. 取消没有完成的连接应采用 CANC ...
- Java Comparator的范型类型推导问题
问题 在项目中,有一处地方需要对日期区间进行排序 我需要以日期区间的开始日为第一优先级,结束日为第二优先级进行排序 代码 我当时写的代码如下: List<Pair<LocalDate, L ...
- java进制转换(无视正负数的差别)
最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤其是对于负数这一方面. 下面和大家分享一下,这里只写了十进制到二进制的转换,其实都是同样的道理 public class Test1 { pub ...
- AspNetCore - MVC实战系列(一)
本章开篇先简单介绍下最近两周自己利用业余时间做的一个图片收集网站,当然这个是靠用户自己上传来收集不是去抓某些个网站的图片,那样没意义,这里我取名为“爱留图”:该网站的简单介绍大家可以参考下上篇的内容爱 ...
- xml语法规则
所有 XML 元素都须有关闭标签 在 HTML,经常会看到没有关闭标签的元素: <p>This is a paragraph <p>This is another paragr ...
- 基于swift MKMapkit 开发的地图定位导航
// DTOneViewController.swift // Mapper-JSON // // Created by kcl on 16/8/8. // Copyright © 2016年 ...
- 安装hexo报错(npm WARN deprecated swig@1.4.2: This package is no longer maintained),已解决
问题:在使用npm安装hexo时报错 $ npm install -g hexo npm WARN deprecated swig@1.4.2: This package is no longer m ...
- [转]ObjectARX二次开发vs编译器版本ARX版本对应说明