• 第7课 缓存策略及并发场景下的分布式锁


    文章说明: 本文是基于盛派网络苏震巍老师的《微信公众号+小程序快速开发》课程笔记。

    课程地址: https://study.163.com/course/courseMain.htm?courseId=1004873017

    本课项目地址:https://github.com/wechatdeveloper/WechatVideoCourse

     

    课程目标:了解Senparc.Weixin SDK 缓存策略;模拟多线程访问产生的并发,使用分布式锁控制并发

     

    Redis 安装:

     

    项目中使用Redis缓存

    • 项目引用 Senparc.Weixin.Cache.Redis

    • Web.config 配置使用缓存: <add key="Cache_Redis_Configuration" value="localhost:6379" />

    • Global.asax 注册测试号,参考 Senparc Sample 项目配置方法

    • 通过Redis Desktop Manager 查询,已经有了 Senparc SDK 产生的缓存数据: 

      

      

    多线程并行,模拟并发

    • 多个进程对同1个数据进行更新操作的时候,会产生并发的情况

    • 控制并发的产生需要加锁,也就进程更新数据的时候加锁,更新完成后释放锁;加锁的过程中,其他需要访问数据的进行,排队等候

    • 建立LockTest方法,方法中对Static类型数据进行更新操作

    • 单元测试中,开启多个线程 执行LockTest()方法模拟数据并发,会发现在抢着更新数据,导致脏读
     1        //Static 保存在内存中,页面观察数据变化
     2         private static int _count;
     3 
     4         public static  int Count
     5         {
     6             get { Thread.Sleep(50); return _count; }
     7     
     8             set
     9             {
    10                 //线程休眠0.1秒;模拟数据更新处理的时间
    11                 Thread.Sleep(100); 
    12                 _count = value;
    13             } 
    14         } 
    15     
    16         public ContentResult LockTest()
    17         {   
    18             var count =  Count; //数据计出来 
    19             Count = count + 1; //数据再更新进去
    20     
    21             string strResult = "Count:"+ count;
    22     
    23             return Content(strResult);
    24         }

     

    • 单元测试中,开启多个线程 执行LockTest()方法模拟数据并发,会发现在抢着更新数据,导致脏读
        private int totalThread = 100; //计划线程要执行次数
        private int finishedThread = 0; 
    
       [TestMethod]
        public void LockTest()
        { 
            //开启多个线程
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(100);//给个线程创建时间
    
                Thread thread = new Thread(RunSingleLockTest);
                thread.Start(); 
            }
    
            while (finishedThread!= totalThread)
            {
                //等待线程执行到100次
            }
    
            Console.WriteLine("线程执行完毕:"+totalThread.ToString());
         
        }
         
        private void RunSingleLockTest()
        {  
            HomeController controller = new HomeController();
    
            ContentResult result = controller.LockTest() as ContentResult;
    
            Console.WriteLine(result.Content);
    
            finishedThread++; //记得线程执行的次数
        }
    

      执行结果:

    用缓存策略,控制并发:把数据读取、更新操作,加锁处理,控制线程排队执行

     1 public ContentResult LockTest()
     2  {
     3             //获取当前缓存实例
     4             var strategy = CacheStrategyFactory.GetObjectCacheStrategyInstance();
     5             using (strategy.BeginCacheLock("HomeController", "LockTest"))
     6             {
     7                 var count = Count; //数据计出来 
     8                 Count = count + 1; //数据再更新进去 
     9                 string strResult = "Count:" + count;
    10                 return Content(strResult);
    11             } 
    12 }

    在并发控制下,线程排队执行结果:数据被顺序更新

     


     

     

     

     

  • 相关阅读:
    eclipse如何把多个项目放在一个文件夹下【eclipse中对项目进行分类管理】-图示详解
    hibernate中cache二级缓存问题
    Java处理正则验证手机号-详解
    Java处理手机号中间4位替换成*
    WPF:依赖属性的应用
    WPF:自定义路由事件的实现
    WPF:类型转换器的实现
    MFC中CString转化为char*
    Android4.4 往短信收件箱中插入自定义短信(伪造短信)
    OpenCV imread读取图片,imshow展示图片,出现cv:Exception at memory location异常
  • 原文地址:https://www.cnblogs.com/WechatDeveloper/p/SenparcWeixinSDK-Course-7.html
Copyright © 2020-2023  润新知