CJCMS系列---說說項目中的緩存實現(1)

緩存者,臨時文件交換區也。主要就是方便查找,提升查找效率(效率在於讀內存速度比讀硬盤快)。程序員

  

   大多數的項目的緩存都是經過設定過時時間來作的,但是我對於這樣的替換策略不覺得然,並且會致使混亂。緩存

 

  有人說:最讓人蛋疼的莫過於命名和緩存了。併發

 

  那麼緩存蛋疼在哪裏呢,那就是容易致使髒數據,緩存不該該成爲髒數據,而大多數時間髒數據不可避免。spa

  

  舉一個例子:淘寶商城,我店裏有一個商品,當時緩存的庫存100,可是遇上光棍節大酬賓,各類併發請求,也許你在買的時候緩存裏面還有20,可是100個訂單已經下過了,可是點擊下單的時候蛋疼的事情來了(固然我以爲淘寶沒有這樣子的問題啦),你竟然下單成功了。我操,我做爲店主很鬱悶啊,我他孃的到哪裏多進口20架米格戰鬥機啊。調試

  

  上面的例子,你對緩存應該也有了一種深惡痛絕的感覺吧。你這時候笑了,笑我寫的程序差,笑我淘寶店的代碼是垃圾,沒錯,這樣的髒數據是可以避免的,但是有多少程序員可以注意到這一點呢,我以爲不多。code

  

  直入主題上代碼,這裏先上一部分後面慢慢講深刻,慢慢改進,畢竟真的是在邊寫文章邊寫例子。對象

    

複製代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CJCMS.Framework.Cache
{
    public  class CacheTarget
    {
        /// <summary>
        /// 緩存對象
        /// </summary>
        public object Target { get; set; }

        /// <summary>
        /// 緩存對象最後使用時間
        /// </summary>
        public DateTime LastRefresh { get; set; }
    }
}
複製代碼

 

  

複製代碼
  1 /******************************************************************
  2 * 做者:                    不要理我 CJ
  3 * 郵件:               869722304@qq.com(僅僅支持商業合做洽談)
  4 * 建立時間:                2012-8-14 19:43:41
  5 * 最後修改時間:            2012-8-14 19:43:41
  6 * 
  7 * 未經修改的文件版權屬於原做者全部,可是你能夠閱讀,修改,調試。本項目不建議商用,不能確保穩定性。
  8 * 同時因爲項目bug引發的一切問題,原做者概不負責。
  9 *
 10 * 本項目所引用的全部類庫,仍然遵循其本來的協議,不得侵害其版權。
 11 *
 12 * 您一旦下載就視爲您已經閱讀此聲明。
 13 *
 14 * 您不能夠移除項目中的任何聲明。
 15 *******************************************************************/
 16 
 17 using System;
 18 using System.Collections.Generic;
 19 using System.Linq;
 20 using System.Text;
 21 
 22 namespace CJCMS.Framework.Cache
 23 {
 24     public class CacheTargetManger //: ICacheTargetManger
 25     {
 26         private static Dictionary<string, CacheTarget> _entries = new Dictionary<string, CacheTarget>();
 27 
 28         /// <summary>
 29         /// 檢測是否緩存空間達到極限,須要使用策略替換
 30         /// </summary>
 31         /// <returns></returns>
 32         public static void CheckIsExpired()
 33         {
 34            
 35             AppDomain.MonitoringIsEnabled = true;
 36 
 37             AppDomain currAppDomain = System.Threading.Thread.GetDomain();
 38             while (true)
 39             {
 40                 GC.Collect();
 41                 if (currAppDomain.MonitoringSurvivedMemorySize > 50 * 1000 * 1000)
 42                 {
 43                     //最近最少使用策略實現
 44                     DoStrategy();
 45                 }
 46                 else
 47                 {
 48                     break;
 49                 }
 50             }
 51         }
 52         /// <summary>
 53         /// 使用了最近最少使用策略
 54         /// </summary>
 55         public static void DoStrategy()
 56         {
 57             try
 58             {
 59                 Remove(_entries.OrderBy(a => a.Value.LastRefresh).First().Key);
 60             }
 61             catch
 62             {
 63                
 64             }
 65         }
 66         /// <summary>
 67         /// 添加新的內容
 68         /// </summary>
 69         /// <param name="key"></param>
 70         /// <param name="cache"></param>
 71         public static void Add(string key, object cache)
 72         {
 73             CacheTarget c = new CacheTarget();
 74             c.Target = cache;
 75             c.LastRefresh = DateTime.Now;
 76             CheckIsExpired();
 77             lock (_entries)
 78             {
 79                 _entries.Add(key, c);
 80             }
 81 
 82         }
 83 
 84         public static void Update(string key, object cache)
 85         {
 86             CacheTarget c = new CacheTarget();
 87             c.Target = cache;
 88             c.LastRefresh = DateTime.Now;
 89 
 90             lock (_entries)
 91             {
 92                 _entries.Remove(key);
 93                 _entries.Add(key, c);
 94             }
 95 
 96         }
 97 
 98         public static void Save(string key, object cache)
 99         {
100             if (_entries.ContainsKey(key))
101             {
102                 Update(key, cache);
103             }
104             else
105             {
106                 Add(key, cache);
107             }
108         }
109 
110         public static void Remove(string key)
111         {
112             lock (_entries)
113             {
114                 _entries.Remove(key);
115             }
116         }
117 
118         public static void FuzzyRemove(string fuzzykey)
119         {
120             foreach (KeyValuePair<string, CacheTarget> k in _entries.Where(a => a.Key.Contains(fuzzykey)).ToList())
121             {
122                 Remove(k.Key);
123             }
124         }
125 
126         public static void Get(string key, out object result)
127         {
128             try
129             {
130                 CacheTarget c = new CacheTarget();
131                 _entries.TryGetValue(key, out c);
132                 result = c.Target;
133                 Update(key, result);
134             }
135             catch
136             {
137                 result = null;
138             }
139         }
140     }
141 }
複製代碼

 

你們先看起來代碼,具體尚未講完,我後面再講。blog

 

泰州人在上海作it qq羣179233261內存

相關文章
相關標籤/搜索