Redis SETNX实现分布式锁
1、某进程1执行 SETNX lock 以尝试获取锁
2、由于某进程2已获得了锁,所以进程1执行 SETNX lock 返回0,即获取锁失败
3、进程1执行 GET lock 来检测锁是否已超时,如果没超时,则线程等待一段时间,再次检测
4、如果进程1检测到锁已超时,即当前的时间大于键 lock 的值,进程1会执行以下操作
GETSET lock <current Unix timestamp + lock timeout + 1>
5、由于 GETSET 操作在设置键的值的同时,还会返回键的旧值,通过比较键 lock 的旧值是否小于当前时间,可以判断进程是否已获得锁
6、假如另一个进程3也检测到锁已超时,并在进程1之前执行了 GETSET 操作,那么进程1的 GETSET 操作返回的是一个大于当前时间的时间戳,这样进程1就不会获得锁而继续等待。注意到,即使进程1接下来将键 lock 的值设置了比进程3设置的更大的值也没影响。
另外,值得注意的是,在进程释放锁,即执行 DEL lock 操作前,需要先判断锁是否已超时。如果锁已超时,那么锁可能已由其他进程获得,这时直接执行 DEL lock 操作会导致把其他进程已获得的锁释放掉。
C# Code
using System;
using System.Threading;
using System.Threading.Tasks;
using CSRedis;
namespace RedisLockDemo
{
public class CsRedisLock
{
private static readonly int _lock_timeout = 40;
private static readonly string _lock_key = "lock";
public static void Test()
{
var rds = new CSRedisClient("127.0.0.1:6379,password=123456,defaultDatabase=13,poolsize=50,ssl=false");
RedisHelper.Initialization(rds);
Parallel.For(0, 13, x =>
{
if (GetLock(_lock_key))
{
Console.WriteLine($"person:{x},线程ID:{Thread.CurrentThread.ManagedThreadId},获得锁 woking");
if (DateTimeOffset.Now.ToUnixTimeMilliseconds() < RedisHelper.Get<long>(_lock_key))
{
//释放锁
RedisHelper.Del(_lock_key);
}
}
else
{
Console.WriteLine($"person:{x},线程ID:{Thread.CurrentThread.ManagedThreadId},获取锁异常");
}
});
Console.WriteLine();
}
private static bool GetLock(string key)
{
bool getLocked = false;
try
{
while (!getLocked)
{
var now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
var lock_time = now + _lock_timeout + 1;
getLocked = RedisHelper.SetNx(key, lock_time);
//判断是否获取锁,
if (getLocked || now > RedisHelper.Get<long>(key) && now > RedisHelper.GetSet<long>(key, lock_time))
{
getLocked = true;
}
else
{
Thread.Sleep(30);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return getLocked;
}
}
}
相关文档:https://redis.io/commands/setnx
Redis SETNX实现分布式锁的更多相关文章
- Redis setNX 实现分布式锁(重复数据插入可用其来实现排他锁)
使用Redis的 SETNX 命令可以实现分布式锁,下文介绍其实现方法. SETNX命令简介 命令格式 SETNX key value 将 key 的值设为 value,当且仅当 key 不存在. 若 ...
- 基于redis实现的分布式锁
基于redis实现的分布式锁 我们知道,在多线程环境中,锁是实现共享资源互斥访问的重要机制,以保证任何时刻只有一个线程在访问共享资源.锁的基本原理是:用一个状态值表示锁,对锁的占用和释放通过状态值来标 ...
- 一个Redis实现的分布式锁
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.conne ...
- 基于Redis的简单分布式锁的原理
参考资料:https://redis.io/commands/setnx 加锁是为了解决多线程的资源共享问题.Java中,单机环境的锁可以用synchronized和Lock,其他语言也都应该有自己的 ...
- 在redis上实现分布式锁
/** *在redis上实现分布式锁 */ class RedisLock { private $redisString; private $lockedNames = []; public func ...
- redis系列:分布式锁
redis系列:分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...
- Redis如何实现分布式锁
今天我们来聊一聊分布式锁的那些事. 相信大家对锁已经不陌生了,我们在多线程环境中,如果需要对同一个资源进行操作,为了避免数据不一致,我们需要在操作共享资源之前进行加锁操作.在计算机科学中,锁(lock ...
- Redis高并发分布式锁详解
为什么需要分布式锁 1.为了解决Java共享内存模型带来的线程安全问题,我们可以通过加锁来保证资源访问的单一,如JVM内置锁synchronized,类级别的锁ReentrantLock. 2.但是随 ...
- redis客户端、分布式锁及数据一致性
Redis Java客户端有很多的开源产品比如Redission.Jedis.lettuce等. Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持:Redis ...
随机推荐
- Kmeans聚类(lena图)
lena512.raw 下载地址:https://files.cnblogs.com/files/jzcbest1016/lena512_20171219131444306.rar .raw文件可以用 ...
- JSP+Oracle实现分页功能
Oracle: create table load( id char(200) not null, title varchar2(100) not null, time varchar2(100) n ...
- Centos 7.x 设置Lvs+ Keepalived
[实验环境] Centos 7.2 Nginx 以下为本次试验所使用的地址: VIP:192.168.136.100 LVS-1:192.168.136.170 LVS-2:192.168.136. ...
- (转)Linux 磁盘IO性能测试
Linux 如何测试 IO 性能(磁盘读写速度) 这几天做MySQL性能测试,偌大一个公司,找几台性能测试机器都很纠结,终于协调到两台,IO的性能如何还不知道.数据库属于IO密集型的应用,所以还是先评 ...
- Layui + 微信小程序 + PC端 + GatewayWorker + 移动端即时聊天系统
- Buuctf pwn1 详细wp
目录 程序基本信息 程序溢出点 确定返回地址 编写exp脚本 成功getshell 程序基本信息 我们可以看到这是一个64程序,没有保护开启. 程序溢出点 gets函数可以读取无限字符,存在栈溢出. ...
- BigDecimal 相关
一.BigDecimal 精度设置 BigDecimal setScale(int newScale, int roundingMode): newScale:小数位数, RoundingMode是一 ...
- Thingsboard学习之一CentOS安装系统更新
首先安装好系统,查询到系统的IP地址后,使用Putty登入系统 更新系统 yum update 安装git yum install git 动图演示
- 【Java】Unicode和字符串互转
Unicode(统一码.万国码.单一码)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一 ...
- openrstry 限流 是否有清零逻辑
openrstry 限流 是否有清零逻辑 https://github.com/openresty/lua-resty-limit-traffic