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"); } } } }