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实现分布式锁代码片段相关推荐

  1. Redis实现分布式锁释放锁

    package com.learn;//什么线程安全问题 在同一个jvm中,多个线程共享同一个全局变量做写的操作的时候,可能会收到其他线程的干扰. class ThreadDemo implement ...

  2. 基于 Redis 实现分布式锁思考

    以下文章来源方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/xuan_lu/article/details/111600302 分布式锁 基于redis实 ...

  3. Redis实现分布式锁的深入探究

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 一.分布式锁简介 锁 是一种用来解决多个执行线程 访问共享资源 错 ...

  4. nx set 怎么实现的原子性_基于Redis的分布式锁实现

    前言 本篇文章主要介绍基于Redis的分布式锁实现到底是怎么一回事,其中参考了许多大佬写的文章,算是对分布式锁做一个总结 分布式锁概览 在多线程的环境下,为了保证一个代码块在同一时间只能由一个线程访问 ...

  5. Zookeeper和Redis实现分布式锁,附我的可靠性分析

    作者:今天你敲代码了吗 链接:https://www.jianshu.com/p/b6953745e341 在分布式系统中,为保证同一时间只有一个客户端可以对共享资源进行操作,需要对共享资源加锁来实现 ...

  6. Redis——由分布式锁造成的重大事故

    作者:浪漫先生 原文:juejin.im/post/6854573212831842311 前言 基于Redis使用分布式锁在当今已经不是什么新鲜事了.本篇文章主要是基于我们实际项目中因为redis分 ...

  7. redis系列:基于redis的分布式锁

    一.介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境, ...

  8. 基于 Redis 的分布式锁到底安全吗?

    [完整版] 网上有关Redis分布式锁的文章可谓多如牛毛了,不信的话你可以拿关键词"Redis 分布式锁"随便到哪个搜索引擎上去搜索一下就知道了.这些文章的思路大体相近,给出的实现 ...

  9. js 拉勾网效果_Node.js 中实践基于 Redis 的分布式锁实现

    在一些分布式环境下.多线程并发编程中,如果对同一资源进行读写操作,避免不了的一个就是资源竞争问题,通过引入分布式锁这一概念,可以解决数据一致性问题. 作者简介:五月君,Nodejs Developer ...

  10. redis做分布式锁可能不那么简单

    在计算机世界里,对于锁大家并不陌生,在现代所有的语言中几乎都提供了语言级别锁的实现,为什么我们的程序有时候会这么依赖锁呢?这个问题还是要从计算机的发展说起,随着计算机硬件的不断升级,多核cpu,多线程 ...

最新文章

  1. SQL 关于apply的两种形式cross apply 和 outer apply
  2. 偏差是什么?一文读懂偏差
  3. 瑞德西韦重症用药结果再曝光,上百名重症一周内好转,股价大涨19%
  4. 系统app无法访问外部存储设备问题
  5. Only the original thread that created a view hierarchy can touch its views——Handler的使用
  6. sqlserver导入向导时提示外部表不是预期格式_Excel办公实操,导入本地数据,创建参数查询,就是简单...
  7. LockSupport的源码实现原理以及应用
  8. 51nod 1040最大公约数和(欧拉函数)
  9. BFS HDOJ 1242 Rescue
  10. 响应式web之@media screen
  11. 【BZOJ2751】【codevs1853】容易题,快速幂+逆元
  12. mysql 大小写问题—20161102
  13. 一键抠图工具有哪些?这5款亲测好用
  14. 西安三本计算机专业可报院校,西安三本大学前十名, 西北大学现代学院仅第四...
  15. 韩国研发AI武器遭抵制,武器自带“头脑”将多可怕
  16. 为什么总跳到国内版(cn.bing.com)?New Bing使用全攻略
  17. flex中换行符的使用
  18. 放榜时刻!RT-Thread应用创新大赛圆满收官
  19. linux系统中的时间
  20. 微信小程序带给我们哪些便利

热门文章

  1. Java如何获取文件编码格式
  2. 控制台应用程序的Main方法
  3. 05、应用程序数据操作(下)
  4. Intent以及IntentFilter详解 1
  5. 【转】uni-app在手持PDA上的激光扫码完美解决方案
  6. plsql设置代码提示和自动补全
  7. pv 6.3升级日志
  8. IO多路复用之select、poll、epoll介绍
  9. springsecurity 登录失败_145-Spring Security
  10. ermaster连接oracle数据库表,window连接远程服务器报函数不支持之解决方案