#region ---分布式锁---
/// <summary>
/// 加锁
/// </summary>
/// <param name="key">锁key</param>
/// <param name="selfMark">自己唯一标记</param>
/// <param name="lockExpirySeconds">锁自动过期时间[默认10](s)</param>
/// <param name="waitLockMilliseconds">等待锁时间(ms)</param>
/// <returns></returns>
public bool Lock(string key, out string selfMark, int lockExpirySeconds = 10, long waitLockMilliseconds = 0)
{
DateTime begin = DateTime.Now;
selfMark = Guid.NewGuid().ToString("N");//自己标记,释放锁时会用到,自己加的锁除非过期否则只能自己打开
using (IRedisClient redisClient = GetClient())
{
string lockKey = "Lock_" + key;
while (true)
{
string script = string.Format("if redis.call('SETNX', KEYS[1], ARGV[1]) == 1 then redis.call('PEXPIRE',KEYS[1],{0}) return 1 else return 0 end", lockExpirySeconds * 1000);
//循环获取取锁
if (redisClient.ExecLuaAsInt(script, new[] { lockKey }, new[] { selfMark }) == 1)
{
return true;
}
//不等待锁则返回
if (waitLockMilliseconds == 0)
{
break;
}
//超过等待时间,则不再等待
if ((DateTime.Now - begin).TotalMilliseconds >= waitLockMilliseconds)
{
break;
}
}
return false;
}
}
/// <summary>
/// 释放锁
/// </summary>
/// <param name="key">锁key</param>
/// <param name="selfMark">自己唯一标记</param>
public void UnLock(string key, string selfMark)
{
using (IRedisClient redisClient = GetClient())
{
string lockKey = "Lock_" + key;
var script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
redisClient.ExecLuaAsString(script, new[] { lockKey }, new[] { selfMark });
}
}
#endregion
for (int i = 1; i <= 50; i++)
{
Task.Run(() =>
{
Random random = new Random();
int userId = random.Next(1, 5);
string lock_key = "user_{0}";
string selfMark = string.Empty;
try
{
lock_key = string.Format(lock_key, userId);
//加锁
if (RedisUtil.Instance().Lock(lock_key, out selfMark, 10, 0))
{
//逻辑代码......
Thread.Sleep(500);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
//解锁
RedisUtil.Instance().UnLock(lock_key, selfMark);
}
});
}