缓存锁
下面是看WINSDK源码,看到缓存锁的时候,一点记录
最初的时候,看到了WINSDK测试代码:
using (var cacheLock = cache.BeginCacheLock(resourceName, appId, (int)retryTimes, new TimeSpan(0, 0, 0, 0, 20))) { var result = cacheLock.LockSuccessful ? "成功" : "【失败!】"; Console.WriteLine("线程 {0} / {1} : {2} 进入锁,等待时间:{3}ms,获得锁结果:{4}", Thread.CurrentThread.GetHashCode(), resourceName, appId, (DateTime.Now - dt1).TotalMilliseconds, result); Thread.Sleep(sleepMillionSeconds); }
为什么用一个Using 调一个加锁的方法,整个处理过程就可以保证都在锁定范围内操作的呢
初始猜测,用Using肯定是实现了IDisposable,一查果然是
当Using块执行完的时候,释放了锁
BeginCacheLock F12查看代码的时候,发现定义到了一个接口里面去了
/// <summary> /// 最底层的缓存策略接口 /// </summary> public interface IBaseCacheStrategy { ///// <summary> ///// 整个Cache集合的Key ///// </summary> //string CacheSetKey { get; set; } /// <summary> /// 创建一个(分布)锁 /// </summary> /// <param name="resourceName">资源名称</param> /// <param name="key">Key标识</param> /// <param name="retryCount">重试次数</param> /// <param name="retryDelay">重试延时</param> /// <returns></returns> ICacheLock BeginCacheLock(string resourceName, string key, int retryCount = 0, TimeSpan retryDelay = new TimeSpan()); }
查找引用发现了BaseCacheStrategy实现了接口IBaseCacheStrategy
但是并没有实现BeginCacheLock,只是把它定义成了抽象方法,强制子类必须实现
查找引用发现:有三个子类继承了BaseCacheStrategy
分别是:
MemcachedObjectCacheStrategy: public override ICacheLock BeginCacheLock(string resourceName, string key, int retryCount = 0, TimeSpan retryDelay = new TimeSpan()) { return new MemcachedCacheLock(this, resourceName, key, retryCount, retryDelay); } RedisObjectCacheStrategy: public override ICacheLock BeginCacheLock(string resourceName, string key, int retryCount = 0, TimeSpan retryDelay = new TimeSpan()) { return new RedisCacheLock(this, resourceName, key, retryCount, retryDelay); } LocalObjectCacheStrategy: public override ICacheLock BeginCacheLock(string resourceName, string key, int retryCount = 0, TimeSpan retryDelay = new TimeSpan()) { return new LocalCacheLock(this, resourceName, key, retryCount, retryDelay); }
那么这三个策略实现什么时候用哪一个,由谁来指定呢,看了下测试接口的实现是有一个:
var cache = CacheStrategyFactory.GetObjectCacheStrategyInstance();//每次重新获取实例(因为单例模式,所以其实是同一个) 来获取对应的策略类
缓存策略工厂里面有两个方法,一个是静态的注册方法 RegisterObjectCacheStrategy
,应该是在应用程序启动的时候注册
另一个是获取 缓存策略实例,应该是根据注册的实例来获取
查看代码:
public static IObjectCacheStrategy GetObjectCacheStrategyInstance() { if (ObjectCacheStrateFunc == null) { //默认状态 return LocalObjectCacheStrategy.Instance; } else { //自定义类型 var instance = ObjectCacheStrateFunc();// ?? LocalObjectCacheStrategy.Instance; return instance; } }
原来没有注册的话,就用本地缓存策略,注册的话用用户指定的
那用户什么时候指定呢
//配置Redis缓存 .RegisterCacheRedis( ConfigurationManager.AppSettings["Cache_Redis_Configuration"], redisConfiguration => (!string.IsNullOrEmpty(redisConfiguration) && redisConfiguration != "Redis配置") ? RedisObjectCacheStrategy.Instance : null) //配置Memcached缓存 .RegisterCacheMemcached( new Dictionary<string, int>() {/* { "localhost", 9101 }*/ }, memcachedConfig => (memcachedConfig != null && memcachedConfig.Count > 0) ? MemcachedObjectCacheStrategy.Instance : null)
在全局配置文件启动的时候指定
下面是缓存策略与锁的UML图