redis分布式锁
来源:互联网 发布:社区控烟网络会议记录 编辑:程序博客网 时间:2024/06/03 19:55
理论:http://blog.csdn.net/ugg/article/details/41894947
代码:http://blog.csdn.net/he90227/article/details/69568702
个人理解:
redis分布式锁主要是从判断(key,value)是否存在来断定是否让线程获取到锁,如果获得锁,执行业务,未获取到锁,不执行业务,阻止并发线程出错。
看自己写的伪代码:
public void lock(String lockKey, String currentThreadTime){ boolean lock = false;//初始化未获取到锁 boolean success = SETNX(lockKey, currentThreadTime); if(success){ //通过命令setnx即获取到了锁(这个资源锁被释放,或者被redis因过期del) expire(currentThreadTime);//设置过期时间,防止因当前线程获取锁后,突然挂掉而导致锁不被释放 lock = true;//代表获取到锁 }else{ //说明该资源被其他线程占了锁 valueTimeStr = GET(lockKey);//获取到锁的时间戳值 if(valueTimeStr != null && valueTimeStr < systemCurrentTime){ //该锁未被其他线程del且过期----A oldValueTimeStr = GETSET(lockKey,currentThreadTime); //当前线程发现锁过期,决定尝试获取用getset获取锁 if(oldValueTimeStr != null && valueTimeStr.equals(oldValueTimeStr)){ //getset命令去获取旧的时间,看从A进来这段代码期间,有没有其他线程也发现过期而del或者修改掉了锁的值 lock = true;//获得锁 }else{ //虽然GET的时候发现锁过期了,但是在准备获取这个锁时,其他线程抢先del或者修改了lockKey的值 sleep(200);//线程死等200毫秒,再看下一次循环 } }else{ //因过期redis服务器删了锁,或者其他线程发现锁过期删了锁 sleep(200);//等待下一次循环 } } }
总结:1、获得锁的两个状态:
a.(lockKey,value)这对键值对未创建,也就是说没有其他线程正在占用该锁时
b. lockKey被占用,但是过期了,且未被其他线程抢先占有,代码片段如下:
oldValueTimeStr != null && valueTimeStr.equals(oldValueTimeStr)
2、锁设置过期时间是为了防止死锁,假设C1线程SETNX成功了,但是突然挂掉了,一直不释放锁,其他线程只能干等,造成死锁
3、使用到的三个命令:
SETNX,GET,GETSET,DEL
问题思考:
1、过期时间设置多长合适,如果业务时间大于锁过期时间,线程C1获取锁后执行业务时,线程C2发现锁过期,然后通过GETSET获取了锁,进而执行业务,那么此时,C1,C2同时执行业务,是不是造成了并发的情况
2、SETNX失败是否直接让线程等待锁过期,被服务器删除后尝试,而不用进行GETSET后面的操作,直接等待
上面两个问题的关键就是,是否存在,线程1获取到锁,但是业务还没执行完,但是锁过期了?
再加一个流程图:
- Redis实现分布式锁
- Redis 分布式锁实现
- Redis 分布式锁实现
- redis 分布式锁
- redis分布式锁
- Redis实现分布式锁
- Redis分布式锁思考
- redis实现分布式锁
- Redis实现分布式锁
- Redis分布式锁
- redis分布式锁
- maven + redis + 分布式锁
- 分布式锁redis实现
- redis分布式锁
- redis分布式锁
- Redis 分布式锁实现
- **redis分布式锁**
- redis分布式锁实现
- 电解电容的ESR,想说三句话
- Ubuntu16.04使用Qt Creator编译时报错“找不到 -lGL”之解决办法
- SSO CAS单点登陆
- 二叉排序
- Oracle 系统权限详细列表
- redis分布式锁
- ReactiveCocoa 讲解
- 推荐系统评测指标
- 笨方法学习Python-习题4:变量(variable)和命名
- 2个惯性环节相乘=1个全部阻尼范围下的二阶振荡环节?
- ContentProviderMedia获取 外部存储的 音频文件
- maven创建web项目报错 Cannot change version of project facet Dynamic web module to 3.0
- iOS进阶开发---致2年开发经验的你
- js 判断iPhone|iPad|iPod|iOS|Android客户端