缓存二字,从字面上分为两块:“缓”与“存”。上节我们提到的缓存原理,其实是在讲的一个“存”字,如何存取。大致回顾下是key对应的hashcode,根据hashcode作为数组下标来存取,因为存在hash冲突,速度虽达不到O(1),但也是非常之快。今天就说下“缓”的策略。
缓,便意味着“暂时”的意思,过一段时间就不再存在或被替换掉了,所以我们要说的其实是缓存的过期策略。在缓存入门篇中,主要提到了Cache类的Insert的方法,其中的几个变化的参数寓意着各种缓存策略,有具体依赖的有按时间的,一一来看。
按过期时间缓存
这种缓存策略最为简单,只要判断当前时间是否超过了指定的过期时间就remove掉该缓存项即可,一般用于不影响大碍的数据,比如论坛帖子列表,热门板块会更新极其频繁,缓存起来最为合适。但是又不能不更新缓存,不然有人发帖和回帖就看不到了,但可以缓存个一两分钟,两分钟后自动过期,重新加载新的列表,这样就不用管了,所以这种缓存策略更倾向于“不用管”的缓存。既然如此,那么我们就自己写一个按时间过期的缓存类吧。下面的这个类非常基础:
/// <summary>
/// 按时间缓存类
/// </summary>
public class CacheByDateTime<TKey,TValue>
{
/// <summary>
/// 内部缓存项
/// </summary>
class CacheItem
{
/// <summary>
/// 缓存的值
/// </summary>
public TValue value { get; set; }
/// <summary>
/// 过期时间
/// </summary>
public DateTime dateTime { get; set; }
}
/// <summary>
/// 缓存数据词典
/// </summary>
private readonly Dictionary<TKey, CacheItem> _dict;
//为了线程安全,需要对dict的操作加锁
private static readonly object LockDict = new object();
public CacheByDateTime()
{
_dict = new Dictionary<TKey, CacheItem>();
}
/// <summary>
/// 添加一个缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="dateTime">过期时间</param>
public void Add(TKey key, TValue value, DateTime dateTime)
{
lock (LockDict)
{