zoukankan      html  css  js  c++  java
  • 使用Dictionary做缓存的一些问题.

    在实际开发过程中,Dictionary是一种经常被用来做缓存的数据结构,既然是用来做缓存,那么不可避免的就要涉及到多线程的问题,如何来合理的使用,这是一个问题,这个问题与实际业务场景有很大关系,通常来说,会有这么几种场景

    1, 一次性写入,不再改变

    2, 存在写入与删除

    对于缓存来说,永远是读操作占了大部分,因此,必须要确保对于读来说,不会影响并发,这是首要的原则,对于那种在读的时候需要lock的必须否定,对于第一种场景,没什么可说的,直接使用Dictionary就行,Dictionary在内容不变的情况下,对于读操作是可以并发的,并且这种情况下读性能是最好的。

    对于第二种场景来说,又要做区分,需要根据缓存列表的预估长度以及写操作频繁度来选择,

    如果预估长度不大或者写操作不频繁,建议通过“不变列表”模式来实现,具体来说,在写操作的代码中,这样写

     1 //_lock为一个静态object,用来做lock操作
     2             //_dict为静态缓存的Dictionary对象
     3             lock(_lock)
     4             {
     5                 //通过ToDictionary浅拷贝出一个新的Dictionary对象
     6                 //这样可以保证原先的_dict对于读操作“不变”,使读操作不收任何并发影响
     7                 var copyDict =_dict.ToDictionary((kv) => kv.Key,(kv)=>kv.Value);
     8                 //这里做新增删除的动作
     9                 copyDict["key"] = "value";
    10                 //修改完成后重新为静态缓存赋值
    11                 _dict = copyDict;
    12             }

    这就是所谓的“不变列表”模式,从这里也可以看出,如果列表长度很大的话,其实每次执行浅拷贝的动作都会有不少的耗时,这个耗时是随着列表的长度线性增长的,这就是为什么这种模式适用于“预估长度不大或者写操作不频繁”这种场景。

    那如果预估长度很大或者写操作很频繁怎么办呢,这个使用就要用到框架中的并行字典了,也就是ConcurrentDictionary,这个是线程安全的字典类,因此可以像单线程操作一样去使用,它的内部已经做了多线程的处理了,唯一的缺点是,在读的时候,由于内部依然会有锁的动作,是不如“不变列表”模式的性能高的。

    以上就是使用Dictionary做缓存时要考虑的问题

  • 相关阅读:
    C++笔记(2018/2/6)
    2017级面向对象程序设计寒假作业1
    谁是你的潜在朋友
    A1095 Cars on Campus (30)(30 分)
    A1083 List Grades (25)(25 分)
    A1075 PAT Judge (25)(25 分)
    A1012 The Best Rank (25)(25 分)
    1009 说反话 (20)(20 分)
    A1055 The World's Richest(25 分)
    A1025 PAT Ranking (25)(25 分)
  • 原文地址:https://www.cnblogs.com/rhwleo/p/6883165.html
Copyright © 2011-2022 走看看