緩存鎖


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM