线程安全Dictionary

public abstract class ReadFreeCache<TKey, TValue>
{
    protected ReadFreeCache()
        : this(null)
    { }

    protected ReadFreeCache(IEqualityComparer<TKey> comparer)
    {
        this.m_storage = new Dictionary<TKey, TValue>(comparer);
    }

    public abstract TValue Create(TKey key);

    private Dictionary<TKey, TValue> m_storage;
    private readonly object m_writeLock = new object();

    public TValue Get(TKey key)
    {
        TValue value;

        if (this.m_storage.TryGetValue(key, out value))
        {
            return value;
        }

        lock (this.m_writeLock)
        {
            if (this.m_storage.TryGetValue(key, out value))
            {
                return value;
            }

            value = this.Create(key);
            var newStorage = this.m_storage.ToDictionary(
                p => p.Key,
                p => p.Value,
                this.m_storage.Comparer);

            newStorage.Add(key, value);
            this.m_storage = newStorage;
        }

        return value;
    }
}
public abstract class ReadWriteCache<TKey, TValue>
{
    protected ReadWriteCache()
        : this(null)
    { }

    protected ReadWriteCache(IEqualityComparer<TKey> comparer)
    {
        this.m_storage = new Dictionary<TKey, TValue>(comparer);
    }

    private readonly Dictionary<TKey, TValue> m_storage;
    private readonly ReaderWriterLockSlim m_rwLock = new ReaderWriterLockSlim();

    protected abstract TValue Create(TKey key);

    public TValue Get(TKey key)
    {
        TValue value;

        this.m_rwLock.EnterReadLock();
        try
        {
            if (this.m_storage.TryGetValue(key, out value))
            {
                return value;
            }
        }
        finally
        {
            this.m_rwLock.ExitReadLock();
        }

        this.m_rwLock.EnterWriteLock();
        try
        {
            if (this.m_storage.TryGetValue(key, out value))
            {
                return value;
            }

            value = this.Create(key);
            this.m_storage.Add(key, value);
        }
        finally
        {
            this.m_rwLock.ExitWriteLock();
        }

        return value;
    }
}
时间: 2024-08-28 03:53:03

线程安全Dictionary的相关文章

C#:Hashtable和Dictionary

Dictionary<TKey, TValue> ()      Hashtable() 第一.存储的数据类型 Hashtable不是泛型的,不是类型安全的:Dictionary是泛型的,是类型安全的: Hashtable的键值都是Object类型的,但是Dictionary的键值的数据类型是可以指定的. 也就是说如果往Hashtable里面存入Object以外的数据类型,则在取出该数据时,需要对其进行显示的类型转换,才能够正常使用.而Dictionary则没有这个问题. 从这方面讲的话,Ha

各科基础详实

一. Java基础部分 1. JAVA的基本数据类型有哪些 ?  String 是不是基本数据类型 ? 2. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 3. Java有没有goto? 7 4. 说说&和&&的区别. 7 5. 在JAVA中如何跳出当前的多重嵌套循环? 7 6. switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 8 7. short s1 = 1; s1 = s1 + 1;有什么

跨域下载图片走的各种弯路和遇到的种种困难

首先声明 ,我是编程菜鸟,刚做编程不久.欢迎拍砖 要实现的功能: 我们一旅游网站(南北游),可以发表游记.富文本,写攻略,上传图片(我们会对图片进行剪切分成大中小等各种图片,方便不同地方调用). 但有一种情况是用户会把自己发表在其他网站的文章复制粘贴到我们网站,结果是我们只存下了图片的链接地址,而没有实际保存图片.在其他地方用到该图片的时候就会出现图片大小不合适或者显示挂图的现象. 解决的办法就是根据用户粘贴的地址,将图片下载到我们的服务器上.然后将文本框中其他网站地址换成自己网站的地址,保存.

记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)

项目上线以来一直存在一个比较揪心的问题,和一个没有信心处理的BUG,那就是在应用程序启动时有可能会导致cpu跑满99%或持续在一个值如50%左右,这样一来对服务器的压力是非常大的,经常出现服务器无法远程的状态,唯有通过PowerShell杀掉对应的w3wp进程才可以解决这个问题. 为什么没有信心处理这个问题 原因非常简单,这个问题是间歇性的,不容易重现的,只会在项目启动时有一定的可能性会发生CPU跑满的问题. 所有可以重现的BUG的处理都不会太难,而类似这种无法重现的BUG是最让人头疼的,因为它

EntityFramework中的线程安全,又是Dictionary

继上次记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)后又再次与Dictionary博弈,这一次是在EntityFramework中的Dictionary. 从一个异常说起 这个异常与上次的异常有着同一个特性:间歇性,碰到类似的异常在信心上就被削弱了一大半... 在第一次看到这个异常的时候觉得解决它非常的简单,无非就是在字典操作的地方加个锁,但仔细看了一会发现这个问题并没有那么简单,可以看到这个异常的最后几个堆栈信息来自System.Data.Entity命名空间,也就是

c# 扩展方法奇思妙用基础篇五:Dictionary&lt;TKey, TValue&gt; 扩展

Dictionary<TKey, TValue>类是常用的一个基础类,但用起来有时确不是很方便.本文逐一讨论,并使用扩展方法解决. 向字典中添加键和值 添加键和值使用 Add 方法,但很多时候,我们是不敢轻易添加的,因为 Dictionary<TKey, TValue>不允许重复,尝试添加重复的键时 Add 方法引发 ArgumentException. 大多时候,我们都会写成以下的样子: var dict = new Dictionary<int, string>()

c#:ThreadPool实现并行分析,并实现线程同步结束

背景: 一般情况下,经常会遇到一个单线程程序时执行对CPU,MEMORY,IO利用率上不来,且速度慢下问题:那么,怎么解决这些问题呢? 据我个人经验来说有以下两种方式: 1.并行.多线程(Parallel.Task.ThreadPool) 2.多进程MutilpleProcess 恰好工作中又一次遇到单线程程序性能低的问题,本次我主要想尝试使用ThreadPool来实现多线程,并且在实现多线程任务同步结束. 测试代码: 1 static void Main(string[] args) 2 {

iOS多线程开发(二)---线程管理

线程管理 线程管理包括创建,配置,退出三部分.主要包括创建线程的成本,线程创建,线程属性配置,线程主体入口函数编写,线程中断等 一,线程创建成本 1,为辅助线程分配的堆栈空间大小,便于系统和进程管理,以及为函数参数和局部变量分配空间 A,内核数据结构(kernel data structures)---大约1KB,This memory is used to store the thread data structures and attributes, much of which is all

Innodb后台线程

1.maste thread 负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性. 2.IO Thread负责IO请求的回调处理.1.0版本之前有4个IO Thread,负责write.read.insert buffer和log IO Thread1.0.x开始,read thread和write thread分别增加到4个,不再使用innodb_file_io_threads参数,而是使用innodb_read_io_threads和innodb_write_io_threads mysq