缓存锁

下面是看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图

 

posted on 2018-03-15 08:48  行周  阅读(1679)  评论(0编辑  收藏  举报

导航