c# 分布式锁

环境:

net4.5

vs2022

目录

单体服务器:

分布式负载服务器:

1、Redis:

2、RedLock:


模拟商品抢购,单个服务器,可以通过本地服务器缓存或数据库锁就可以处理,

分布式服务器的话,想要实现进程与进程之间实现同步锁,可以使用redis、数据库锁、ZooKeeper来实现。

单体服务器:

可以通过HttpRuntime.Cache缓存来简单实现

public class RuntimeCacheLock
    {
        private static System.Web.Caching.Cache cache = HttpRuntime.Cache;
        private static readonly object lockObj = new object();
        public bool GetLock(string lockKey, object value, int lockExpirySeconds = 10, double waitLockSeconds = 0)
        {
            DateTime begin = DateTime.Now;

            while (true)
            {
                lock (lockObj)
                {
                    //循环获取取锁
                    if (object.ReferenceEquals(cache.Get(lockKey), null))
                    {
                        //设置锁的过期时间
                        cache.Add(lockKey, value, null, DateTime.UtcNow.AddSeconds(lockExpirySeconds),
                System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
                        return true;
                    }
                }

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

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

        public object GetLockValue(string lockKey)
        {
            object obj = cache.Get(lockKey);
            if (obj != null)
            {
                return obj;
            }
            return null;
        }

        public void ReleaseLock(string key)
        {
            cache.Remove(key);
        }
    }
}

program:

class Program
{
        static void Main(string[] args)
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}");
            for (int i = 0; i < 50; i++)
            {
                ThreadPool.QueueUserWorkItem((t) =>
                {
                    Show();
                });
            }
            Console.ReadKey();
        }


        private static int value = 30;
        private static void Show()
        {
            string key = nameof(Show);
            string guid = Guid.NewGuid().ToString();
            RuntimeCacheLock runtimeCacheLock = new RuntimeCacheLock();
            try
            {
                if (runtimeCacheLock.GetLock(key, guid, 5, 10))
                {
                    value--;
                    Thread.Sleep(1000);//模拟业务操作
                    if (value <= 0)
                    {
                        Console.WriteLine($"商品已经无货");
                        return;
                    }
                    else
                    {
                        Console.WriteLine($"value={value}");
                        return;
                    }
                }
                else
                {
                    Console.WriteLine("稍后重试");
                    return;
                }
            }
            finally
            {
                if (runtimeCacheLock.GetLockValue(key) != null && guid.Equals(runtimeCacheLock.GetLockValue(key)))
                    runtimeCacheLock.ReleaseLock(key);
            }
        }
}

分布式负载服务器:

1、Redis:

单节点

引用CSRedisCore库,版本3.6.8.0

    public class RedisLock
    {
        public RedisLock()
        {
            var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379");
            RedisHelper.Initialization(csredis);//初始化
        }

        public bool GetLock(string lockKey, object value, int lockExpirySeconds = 10, double waitLockSeconds = 0)
        {
            DateTime begin = DateTime.Now;

            while (true)
            {
                if (RedisHelper.SetNx(lockKey, value))//key值不存在时,设置缓存
                {
                    RedisHelper.Expire(lockKey, lockExpirySeconds);
                    return true;
                }

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

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

        public object GetLockValue(string lockKey)
        {
            string obj = RedisHelper.Get(lockKey);
            if (obj != null)
            {
                return obj;
            }
            return null;
        }

        public void ReleaseLock(string key)
        {
            RedisHelper.Del(key);
        }
    }

program:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}");
            for (int i = 0; i < 50; i++)
            {
                ThreadPool.QueueUserWorkItem((t) =>
                {
                    RedisShow();
                });
            }
            Console.ReadKey();
        }


        private static int value = 30;

        private static void RedisShow()
        {
            string key = nameof(RedisShow);
            string guid = Guid.NewGuid().ToString();
            RedisLock @lock= new RedisLock();
            try
            {
                if (@lock.GetLock(key, guid, 5, 10))
                {
                    value--;
                    Thread.Sleep(1000);
                    if (value <= 0)
                    {
                        Console.WriteLine($"商品已经无货");
                        return;
                    }
                    else
                    {
                        Console.WriteLine($"value={value}");
                        return;
                    }
                }
                else
                {
                    Console.WriteLine("稍后重试");
                    return;
                }
            }
            finally
            {
                if (@lock.GetLockValue(key) != null && guid.Equals(@lock.GetLockValue(key)))
                    @lock.ReleaseLock(key);
            }
        }

}

2、RedLock:

多个单节点redis组成

引用RedLockNet库,版本2.1.0.0

internal class RedLock
    {
        private static RedLockFactory _redlockFactory;
        static RedLock()
        {
            var endPoints = new List<RedLockEndPoint>
            {
                new DnsEndPoint("localhost", 6379),
                //new DnsEndPoint("redis2", 6379),
                //new DnsEndPoint("redis3", 6379)
            };
            _redlockFactory = RedLockFactory.Create(endPoints);
        }

        private IRedLock _redLock;

        public bool GetLock(string lockKey, object value, int lockExpirySeconds = 10, double waitLockSeconds = 10)
        {
            var expiry = TimeSpan.FromSeconds(lockExpirySeconds);//过期时间
            var wait = TimeSpan.FromSeconds(waitLockSeconds);//等待时间
            var retry = TimeSpan.FromSeconds(2);//重试时间
            _redLock = _redlockFactory.CreateLock(lockKey, expiry, wait, retry);
            //确保获取到锁
            if (_redLock.IsAcquired)
            {
                return true;
            }
            return false;
        }

        public object GetLockValue(string lockKey)
        {
            return string.Empty;
        }

        public void ReleaseLock(string lockKey)
        {
            if (_redLock != null)
                _redLock.Dispose();
            //if (_redlockFactory != null)
            //    _redlockFactory.Dispose();
        }
    }

program:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}");
            for (int i = 0; i < 50; i++)
            {
                RedLock @lock = new RedLock();
                ThreadPool.QueueUserWorkItem((t) =>
                {
                    RedLockShow(@lock);
                });
            }
            Console.ReadKey();
        }

        private static int value = 30;

private static void RedLockShow(RedLock @lock)
        {
            string key = nameof(RedLockShow);
            string guid = Guid.NewGuid().ToString();
            try
            {
                if (@lock.GetLock(key, guid, 10, 20))
                {
                    value--;
                    Thread.Sleep(1000);
                    if (value <= 0)
                    {
                        Console.WriteLine($"商品已经无货");
                        return;
                    }
                    else
                    {
                        Console.WriteLine($"value={value}");
                        return;
                    }
                }
                else
                {
                    Console.WriteLine("稍后重试");
                    return;
                }
            }
            finally
            {
                @lock.ReleaseLock(key);
            }
        }

}

参考:【分布式锁】三种分布式锁的实现【原创】_一直加班的程序猿-CSDN博客

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值