Redis 实现简单的分布式锁
var tasks = new List<Task>();
var count = 0;
for (int i = 0; i < 5; i++)
{
tasks.Add(Task.Run(() =>
{
var state = false;
var ID = Guid.NewGuid().ToString("N");
//申请标志位
while (!state && count < 15 * 10)
{
state = RedisCache.Set(CacheManage.GetServerIDKey(), ID, new TimeSpan(0, 0, 15), When.NotExists);
if (state)
{
log.ExInfo($"{ID}:申请到标志位!");
break;
}
else
{
log.ExInfo($"{ID}:等待");
}
Thread.Sleep(1000);
count++;
}
if (state)
{
Console.WriteLine($"{ID}:处理自己的 事情!");
Thread.Sleep(5 * 1000);
var id = RedisCache.Get(CacheManage.GetServerIDKey());
log.ExInfo($"当前Reids标志位:{id},服务自己的标志位:{ID}");
if (id == ID)
{
RedisCache.Remove(CacheManage.GetServerIDKey());
log.ExInfo($"{ID}:移除自己的标志位!");
}
}
else
{
log.ExError(new Exception($"{ID}:在指定时间未获取到标志位!"));
}
}));
}
Task.WaitAll(tasks.ToArray());
Console.ReadLine();
效果也是很明显哦


新增加一个类,方便操作
/// <summary>
/// 实现一个redis锁,实现对特定资源的占用
/// </summary>
public class RedisLock
{
private RedisCache redisCache;
private string key;
private string value;
private TimeSpan TimeSpan;
private TimeSpan TimeOut;
public RedisLock(RedisCache redisCache, string key, string value, TimeSpan timeSpan, TimeSpan? timeout = null)
{
this.key = key;
this.value = value;
this.TimeSpan = timeSpan;
this.TimeOut = timeout.HasValue ? timeout.Value : timeSpan.Add(new TimeSpan(0, 0, 2));
this.redisCache = redisCache;
}
/// <summary>
/// 处理动作
/// </summary>
public bool Process(Action<bool> action)
{
bool state = false;
try
{
state = Lock();
if (state)
{
action?.Invoke(state);
}
}
finally
{
UnLock(state);
}
return state;
}
/// <summary>
/// 申请锁
/// </summary>
/// <returns></returns>
private bool Lock()
{
DateTime dateTime = DateTime.Now;
var state = false;
//申请标志位
while (!state && (DateTime.Now - dateTime) < TimeOut)
{
state = redisCache.Set(key, value, TimeSpan, When.NotExists);
if (state)
{
break;
}
SpinWait.SpinUntil(() => false, 200);
}
return state;
}
/// <summary>
/// 释放锁
/// </summary>
/// <returns></returns>
private bool UnLock(bool lockState)
{
if (lockState)
{
redisCache.Remove(key);
}
else
{
var data = redisCache.Get(key);
if (data == value)
{
redisCache.Remove(key);
}
}
return true;
}
}
public static void Test()
{
var RedisCache = new RedisCache(ConfigManage.Bind<RedisConfig>("RedisConfig"));
var log = LogManager.GetLogger("DefaultLog");
var tasks = new List<Task>();
for (int i = 0; i < 5; i++)
{
tasks.Add(Task.Run(() =>
{
var state = false;
var ID = Guid.NewGuid().ToString("N");
var redislock = new RedisLock(RedisCache, "key", ID, new TimeSpan(0, 0, 15), new TimeSpan(0, 0, 15 * 10));
redislock.Process(()=> {
log.ExInfo($"{ID}:申请到标志位!");
Console.WriteLine($"{ID}:处理自己的 事情!");
Thread.Sleep(5 * 1000);
});
}));
}
Task.WaitAll(tasks.ToArray());
Console.ReadLine();
}

浙公网安备 33010602011771号