hi,你好!欢迎访问本站!登录
本站由阿里云强力驱动
当前位置:首页 - 文章 - 数 据 库 - 正文 佛曰:你二大爷还是你二大爷。

Redis锁的简朴运用引见_数据库,Redis

2019-12-03数 据 库ki4网10°c
A+ A-

其实说多线程修正数据也不合适,毕竟redis服务端是单线程的,一切敕令串行实行,只是在客户端并发发送敕令的时候,致使串行的敕令一些分列问题和收集时候差等形成数据不一致。本文虽然是数字的加减,然则为了申明锁的状况,有意不是用原子敕令incr。(引荐:redis视频教程)

先配上一个浅易的RedisHelper,一个set值,一个get值,一个设置并发锁,以便在我背面的操纵中,你能清晰我终究做了什么。

public class RedisHelper
    {
        public RedisClient client = new RedisClient("127.0.0.1", 6379);
        public void Set<T>(string key, T val)
        {
            client.Set(key, val);
        }
        public T Get<T>(string key)
        {
            var result = client.Get<T>(key);
            return result;
        }
        public IDisposable Acquire(string key)
        {
           return  client.AcquireLock(key);
        }
    }

下面看一下并发代码,我只new了两个Thread。两个线程同时想接见统一个key,离别接见五万次,在并发条件下,我们很难保证数据的准确性,请比较输出效果。

static void Main(string[] args)
        {
            RedisHelper rds = new RedisHelper();
            rds.Set<int>("mykey1", 0);
            Thread myThread1 = new Thread(AddVal);
            Thread myThread2 = new Thread(AddVal);
            myThread1.Start();
            myThread2.Start();
            Console.WriteLine("守候两个线程完毕");
            Console.ReadKey();
        }

        public static void AddVal()
        {
            RedisHelper rds = new RedisHelper();
            for (int i = 0; i < 50000; i++)
            {
                
                    int result = rds.Get<int>("mykey1");
                    rds.Set<int>("mykey1", result + 1);
                
            }
            Console.WriteLine("线程完毕,输出" + rds.Get<int>("mykey1"));
        }

是的,和我们单线程,跑两个50000,会输出100000。现在是两个并发线程同时跑在因为并发形成的数据效果每每不是我们想要的。那末怎样处理这个问题呢,Redis已为我们预备好了!

你能够看到我RedisHelper中有个要领是 public IDisposable Acquire(string key)。 也能够看到他返回的是IDisposable,证实我们须要手动开释资本。

要领内部的 AcquireLock恰是症结的地方,它像redis中讨取一把锁头,被锁住的资本,只能被单个线程接见,不会被两个线程同时get或许set,这两个线程一定是交替着举行的,固然这里的交替并非指你一次我一次,也多是你屡次,我一次,下面看代码。

static void Main(string[] args)
        {
            RedisHelper rds = new RedisHelper();
            rds.Set<int>("mykey1", 0);
            Thread myThread1 = new Thread(AddVal);
            Thread myThread2 = new Thread(AddVal);
            myThread1.Start();
            myThread2.Start();
            Console.WriteLine("守候两个线程完毕");
            Console.ReadKey();
        }

        public static void AddVal()
        {
            RedisHelper rds = new RedisHelper();
            for (int i = 0; i < 50000; i++)
            {
                using (rds.Acquire("lock"))
                {
                    int result = rds.Get<int>("mykey1");
                    rds.Set<int>("mykey1", result + 1);
                }
            }
            Console.WriteLine("线程完毕,输出" + rds.Get<int>("mykey1"));
        }

能够看到我运用了using,挪用我的Acquire要领猎取锁。

输出效果末了是100000,恰是我们要的准确效果。前面的8W+是因为两个线程之一先实行完毕了。

另有,在正式运用的过程当中,发起给我们的锁,运用后删撤除,并加上一个逾期时候,运用expire。

以防止顺序实行时期不测退出,致使锁一向存在,以后大概没法更新或许猎取此被锁住的数据。

你也能够尝试一下不设置expire,在顺序刚开始实行时,封闭console,从新运转顺序,并且在redis-cli的操纵控制台,get你锁住的值,将会永久猎取不到。

一切衔接此redis实例的机械,统一时候,只能有一个猎取指定name的锁.

下面是StackExchange.Redis的写法

var info = "name-"+Environment.MachineName;
            //假如5秒不开释锁 自动开释。防止死锁
            if (db.LockTake("name", info, TimeSpan.FromSeconds(5)))
            {
                try
                {
                   
                }
                catch (Exception ex)
                {
                    
                }
                finally
                {
                   
                    db.LockRelease("name", token);
                }
            }

更多redis学问请关注redis数据库教程栏目。

以上就是Redis锁的简朴运用引见的细致内容,更多请关注ki4网别的相干文章!

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
Redis锁的简朴运用引见_数据库,Redis

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
标签:

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>