redis实现分布式锁代码片段
getset()
这个命令主要有两个参数 getset(key,newValue)。该方法是原子的,对 key 设置 newValue 这个值,并且返回 key 原来的旧值。假设 key 原来是不存在的,那么多次执行这个命令,会出现下边的效果:
- getset(key, “value1”) 返回 null 此时 key 的值会被设置为 value1
- getset(key, “value2”) 返回 value1 此时 key 的值会被设置为 value2
- 依次类推!
使用步骤
- setnx(lockkey, 当前时间+过期超时时间),如果返回 1,则获取锁成功;如果返回 0 则没有获取到锁,转向 2。
- get(lockkey) 获取值 oldExpireTime ,并将这个 value 值与当前的系统时间进行比较,如果小于当前系统时间,则认为这个锁已经超时,可以允许别的请求重新获取,转向 3。
- 计算 newExpireTime = 当前时间+过期超时时间,然后 getset(lockkey, newExpireTime) 会返回当前 lockkey 的值currentExpireTime。
- 判断 currentExpireTime 与 oldExpireTime 是否相等,如果相等,说明当前 getset 设置成功,获取到了锁。如果不相等,说明这个锁又被别的请求获取走了,那么当前请求可以直接返回失败,或者继续重试。
- 在获取到锁之后,当前线程可以开始自己的业务处理,当处理完毕后,比较自己的处理时间和对于锁设置的超时时间,如果小于锁设置的超时时间,则直接执行 delete 释放锁;如果大于锁设置的超时时间,则不需要再锁进行处理。
import cn.com.tpig.cache.redis.RedisService;
import cn.com.tpig.utils.SpringUtils;//redis分布式锁
public final class RedisLockUtil {private static final int defaultExpire = 60;private RedisLockUtil() {//}/*** 加锁* @param key redis key* @param expire 过期时间,单位秒* @return true:加锁成功,false,加锁失败*/public static boolean lock(String key, int expire) {RedisService redisService = SpringUtils.getBean(RedisService.class);long status = redisService.setnx(key, "1");if(status == 1) {redisService.expire(key, expire);return true;}return false;}public static boolean lock(String key) {return lock2(key, defaultExpire);}/*** 加锁* @param key redis key* @param expire 过期时间,单位秒* @return true:加锁成功,false,加锁失败*/public static boolean lock2(String key, int expire) {RedisService redisService = SpringUtils.getBean(RedisService.class);long value = System.currentTimeMillis() + expire;long status = redisService.setnx(key, String.valueOf(value));if(status == 1) {return true;}long oldExpireTime = Long.parseLong(redisService.get(key, "0"));if(oldExpireTime < System.currentTimeMillis()) {//超时long newExpireTime = System.currentTimeMillis() + expire;long currentExpireTime = Long.parseLong(redisService.getSet(key, String.valueOf(newExpireTime)));if(currentExpireTime == oldExpireTime) {return true;}}return false;}public static void unLock1(String key) {RedisService redisService = SpringUtils.getBean(RedisService.class);redisService.del(key);}public static void unLock2(String key) { RedisService redisService = SpringUtils.getBean(RedisService.class); long oldExpireTime = Long.parseLong(redisService.get(key, "0")); if(oldExpireTime > System.currentTimeMillis()) { redisService.del(key); }}
}
public void drawRedPacket(long userId) {String key = "draw.redpacket.userid:" + userId;boolean lock = RedisLockUtil.lock2(key, 60);if(lock) {try {//抢购操作} finally {//释放锁RedisLockUtil.unLock(key);}} else {new RuntimeException("抢购奖励");}
}
参考:https://www.cnblogs.com/seesun2012/p/9214653.html
转载于:https://www.cnblogs.com/wonder2636/p/10840109.html
redis实现分布式锁代码片段相关推荐
- Redis实现分布式锁释放锁
package com.learn;//什么线程安全问题 在同一个jvm中,多个线程共享同一个全局变量做写的操作的时候,可能会收到其他线程的干扰. class ThreadDemo implement ...
- 基于 Redis 实现分布式锁思考
以下文章来源方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/xuan_lu/article/details/111600302 分布式锁 基于redis实 ...
- Redis实现分布式锁的深入探究
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 一.分布式锁简介 锁 是一种用来解决多个执行线程 访问共享资源 错 ...
- nx set 怎么实现的原子性_基于Redis的分布式锁实现
前言 本篇文章主要介绍基于Redis的分布式锁实现到底是怎么一回事,其中参考了许多大佬写的文章,算是对分布式锁做一个总结 分布式锁概览 在多线程的环境下,为了保证一个代码块在同一时间只能由一个线程访问 ...
- Zookeeper和Redis实现分布式锁,附我的可靠性分析
作者:今天你敲代码了吗 链接:https://www.jianshu.com/p/b6953745e341 在分布式系统中,为保证同一时间只有一个客户端可以对共享资源进行操作,需要对共享资源加锁来实现 ...
- Redis——由分布式锁造成的重大事故
作者:浪漫先生 原文:juejin.im/post/6854573212831842311 前言 基于Redis使用分布式锁在当今已经不是什么新鲜事了.本篇文章主要是基于我们实际项目中因为redis分 ...
- redis系列:基于redis的分布式锁
一.介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境, ...
- 基于 Redis 的分布式锁到底安全吗?
[完整版] 网上有关Redis分布式锁的文章可谓多如牛毛了,不信的话你可以拿关键词"Redis 分布式锁"随便到哪个搜索引擎上去搜索一下就知道了.这些文章的思路大体相近,给出的实现 ...
- js 拉勾网效果_Node.js 中实践基于 Redis 的分布式锁实现
在一些分布式环境下.多线程并发编程中,如果对同一资源进行读写操作,避免不了的一个就是资源竞争问题,通过引入分布式锁这一概念,可以解决数据一致性问题. 作者简介:五月君,Nodejs Developer ...
- redis做分布式锁可能不那么简单
在计算机世界里,对于锁大家并不陌生,在现代所有的语言中几乎都提供了语言级别锁的实现,为什么我们的程序有时候会这么依赖锁呢?这个问题还是要从计算机的发展说起,随着计算机硬件的不断升级,多核cpu,多线程 ...
最新文章
- SQL 关于apply的两种形式cross apply 和 outer apply
- 偏差是什么?一文读懂偏差
- 瑞德西韦重症用药结果再曝光,上百名重症一周内好转,股价大涨19%
- 系统app无法访问外部存储设备问题
- Only the original thread that created a view hierarchy can touch its views——Handler的使用
- sqlserver导入向导时提示外部表不是预期格式_Excel办公实操,导入本地数据,创建参数查询,就是简单...
- LockSupport的源码实现原理以及应用
- 51nod 1040最大公约数和(欧拉函数)
- BFS HDOJ 1242 Rescue
- 响应式web之@media screen
- 【BZOJ2751】【codevs1853】容易题,快速幂+逆元
- mysql 大小写问题—20161102
- 一键抠图工具有哪些?这5款亲测好用
- 西安三本计算机专业可报院校,西安三本大学前十名, 西北大学现代学院仅第四...
- 韩国研发AI武器遭抵制,武器自带“头脑”将多可怕
- 为什么总跳到国内版(cn.bing.com)?New Bing使用全攻略
- flex中换行符的使用
- 放榜时刻!RT-Thread应用创新大赛圆满收官
- linux系统中的时间
- 微信小程序带给我们哪些便利