redis 分布式锁

在我们的日常开发中,一个进程中当多线程的去竞争某一资源的时候,我们通常会用一把锁来保证只有一个线程获取到资源。如加上synchronize关键字或ReentrantLock锁等操作。

那么,如果是多个进程相互竞争一个资源,如何保证资源只会被一个操作者持有呢?

 

 辅助类

using CSRedis;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace RedisLock
{
    public static class RedisServer
    {


        public static string CacheStr = "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:";

        public static CSRedisClient Cache;
        public static CSRedisClient Session;

        public static void Initalize()
        {
            Cache = new CSRedisClient(CacheStr);
            // Session = new CSRedisClient(AppSettings.GetConfig("RedisServer:Session"));
        }

        /// <summary>
        /// 分布式锁
        /// </summary>
        /// <param name="key">锁KEY</param>
        /// <param name="lockExpirySeconds">锁自动超时时间</param>
        /// <param name="waitLockSeconds">等待锁的时间</param>
        /// <returns></returns>
        public static bool Lock(string key, int lockExpirySeconds = 10, double waitLockSeconds = 0)
        {

            //间隔等待50毫秒
            int waitIntervMs = 50;

            string lockKey = "LockForSetNX" + key;
            DateTime begin = DateTime.Now;

            while (true)
            {

                //   var aa = Cache.SetNx(lockKey, "1");
                //循环获取锁
                if (Cache.SetNx(lockKey, "1") == true)
                {
                    //设置锁的过期时间
                    Cache.Expire(lockKey, lockExpirySeconds);
                    return true;
                }

                if (waitLockSeconds == 0) break;

                //超过等待时间,则不再等待
                if ((DateTime.Now - begin).TotalSeconds >= waitLockSeconds) break;

                Thread.Sleep(waitIntervMs);

            }
            return false;

        }



        /// <summary>
        /// 释放锁
        /// </summary>
        /// <param name="key"></param>
        public static void DellLock(string key)
        {


            string lockKey = "LockForSetNX" + key;

            Cache.Del(lockKey);



        }

    }
}

 

using System;

namespace RedisLock
{
    internal class Program
    {
        static void Main(string[] args)
        {
            RedisServer.Initalize();
            RedisServer.Cache.Set("aa", "sadasd");
            var text = RedisServer.Cache.Get("aa");

            try
            {
                //取锁,设置KEY10秒后失效,最大等待5秒
                var isLock = RedisServer.Lock("LockKey", 10, 5);
                if (isLock)
                {

                    //取到锁执行具体业务
                    //列入商品购买,库存-1
                    Console.WriteLine("库存-1");

                }

            }
            catch (Exception)
            {

                throw;
            }
            finally
            {

                //释放锁
                RedisServer.DellLock("LockKey");
                Console.WriteLine("释放锁");
            }


            Console.WriteLine("Hello World!");
        }



    }
}

 

 

 

 

 

 

 

 

 

 

 

简单的分布式锁

posted @ 2022-09-25 12:46  比特币大暴涨  阅读(25)  评论(0编辑  收藏  举报