csrediscore实现分布式锁 小计

参考文章: https://segmentfault.com/a/1190000018106844

项目使用的csrediscore, 下面是锁定/解锁2个方法

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

namespace ConsoleApp1
{
    public static class RedisLock
    {
        /// <summary>
        /// 分布式锁
        /// </summary>
        /// <param name="key">锁key</param>
        /// <param name="lockExpirySeconds">锁自动超时时间(秒)</param>
        /// <param name="waitLockMs">等待锁时间(秒)</param>
        /// <returns></returns>
        public static bool Lock(string key, int lockExpirySeconds = 10, double waitLockSeconds = 0)
        {
            //间隔等待50毫秒
            int waitIntervalMs = 50;

            string lockKey = "LockForSetNX:" + key;

            DateTime begin = DateTime.Now;
            while (true)
            {
                //循环获取取锁
                if (RedisHelper.SetNx(lockKey, 1))
                {
                    //设置锁的过期时间
                    RedisHelper.Expire(lockKey, lockExpirySeconds);
                    return true;
                }

                //不等待锁则返回
                if (waitLockSeconds == 0) break;

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

                Thread.Sleep(waitIntervalMs);
            }
            return false;

        }

        /// <summary>
        /// 删除锁 执行完代码以后调用释放锁
        /// </summary>
        /// <param name="key"></param>
        public static void DelLock(string key)
        {
            string lockKey = "LockForSetNX:" + key;
            RedisHelper.Del(lockKey);
        }
    }
}

 

程序中使用

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        private static int count = 0;
        static void Main(string[] args)
        {
            var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379,defaultDatabase=1,syncTimeout=3000,WriteBuffer=102400");
            //初始化 RedisHelper
            RedisHelper.Initialization(csredis);

            for (int i = 0; i < 100; i++)
            {
                var k = i;
                Task.Run(() =>
                {
                    add(k);
                });
                //Thread.Sleep(500);
            }

            Console.WriteLine("count=" + count);
            Console.ReadLine();
        }

        static void add(int k)
        {
            try
            {
                //取锁,设置key10秒后失效,最大等待锁5秒
                if (RedisLock.Lock("LockKey", 5, 2))
                {
                    //取到锁,执行具体业务
                    count++;
                    Console.WriteLine("我拿到锁了++++++++,我是: " + k + " ,count现在值:" + count + " ,当前时间: " + DateTime.Now);
                    Thread.Sleep(2000);

                    //释放锁
                    Console.WriteLine("解锁 : 我是" + k + " ,当前时间: " + DateTime.Now);
                    RedisLock.DelLock("LockKey");
                    return;
                }

                Console.WriteLine("其他人在用,我是: " + k + " ,count现在值:" + count + " ,当前时间: " + DateTime.Now);
                return;
            }
            finally
            {
                ////不能再finally解锁, finally在return前执行 ,起不到锁的作用
                //Console.WriteLine("解锁 : 我是" + k + " ,当前时间: " + DateTime.Now);
                //RedisLock.DelLock("LockKey");
            }
        }
    }
}

 

posted @ 2020-02-20 20:14  小谭行天下  阅读(2365)  评论(0编辑  收藏  举报