Redis SETNX命令实现分布式锁
来源:互联网 发布:女生围巾推荐 知乎 编辑:程序博客网 时间:2024/05/24 00:09
SETNX命令简介
命令格式
SETNX key value
将 key 的值设为 value,当且仅当 key 不存在。
若给定的 key 已经存在,则 SETNX 不做任何动作。
SETNX 是SET if Not eXists的简写。
返回值
设置成功,返回 1 。
设置失败,返回 0 。
使用SETNX实现分布式锁
/** * 使用Redis实现分布式全局锁 * 算法实现参考:http://redis.io/commands/setnx * @author shenhaiwen * */public class RedisDistributeLock { private String lockName; private long expireTime; private RedisOperator redisOper; /** * * @param lockName 同一个名称表示同一把锁 * @param expireTime 锁的超时时间,如果超过,该锁失效,其他线程可获取锁 * @param redisOper */ public RedisDistributeLock(String lockName,long expireTime,RedisOperator redisOper){ this.lockName = lockName; this.redisOper = redisOper; this.expireTime = expireTime * 1000; } private String getLockKey(){ if(StringUtils.isBlank(lockName)) return null; return "lock:" + lockName; } /** * 抛出异常或返回-1,说明未获取到锁 * return: 返回值需要在unlock时作为参数传入 * @param timeout -1:永久等待 * @throws Exception */ public long lock(long timeout) throws Exception{ String key = getLockKey(); if(key == null) throw new Exception("lock must have a name"); boolean infinite = (timeout == -1); while(infinite || timeout >= 0){ Long value = System.currentTimeMillis() + expireTime; long keyTimeout = value.longValue(); long setnxRet = redisOper.insertKeyValueIfNotExist(key, value.toString(), -1, null); if(setnxRet > 0){ return keyTimeout; //暂无其他线程或进程加锁 } if(setnxRet == -1){ return -1; } //已经有锁了 String val = redisOper.getValueByKey(key); if(StringUtils.isBlank(val)){ //key刚好被删除了,重来 continue; } if(System.currentTimeMillis() > Long.parseLong(val)){ Long newVal = System.currentTimeMillis() + expireTime; String oldVal = redisOper.getset(key, newVal.toString(), -1, null); if(StringUtils.isBlank(val)){ //key刚好被删除了,重来 continue; } if(System.currentTimeMillis() > Long.parseLong(oldVal)){ keyTimeout = newVal.longValue(); return keyTimeout; } } } if(!infinite){ timeout -= 100; } Thread.sleep(100); return -1; } /** * * @param keyTimeout lock的返回值 */ public void unlock(long keyTimeout){ if(System.currentTimeMillis() > keyTimeout){ return; } redisOper.deleteKeyValue(getLockKey()); } public String getLockName() { return lockName; } public long getExpireTime() { return expireTime; }}
1 0
- 【Redis】 redis setnx命令实现分布式锁
- 使用Redis SETNX 命令实现分布式锁
- Redis SETNX 命令实现分布式锁
- 使用Redis SETNX 命令实现分布式锁
- Redis SETNX命令实现分布式锁
- 使用Redis SETNX 命令实现分布式锁
- 实现分布式锁:Redis SETNX 命令
- 使用Redis SETNX 命令实现分布式锁
- 使用Redis SETNX 命令实现分布式锁
- 使用Redis SETNX 命令实现分布式锁
- 使用Redis SETNX 命令实现分布式锁
- 使用Redis SETNX 命令实现分布式锁
- redis分布式锁-SETNX实现
- redis分布式锁-SETNX实现
- redis分布式锁-SETNX实现
- redis分布式锁-SETNX实现
- redis setnx 实现分布式锁和单机锁
- 谈谈Redis的SETNX分布式锁
- 【JAVA笔记】习题:尝试编写一个矩形类,将长与宽作为矩形类的属性,在构造方法中将长,宽初始化,定义一个成员方法求此矩形的面积。
- MongoDB数据库恢复
- git把本地项目上传到github上
- java GC机制与内存分配策略
- 《CSS权威指南》读书笔记7
- Redis SETNX命令实现分布式锁
- 数据库
- 写程序熟悉read()、write()、stat()、open()、access()等函数
- 如何利用Oracle外部表导入文本文件的数据
- 架构设计之Spring-Session分布式集群会话管理
- swustoj蛇形填数(1183)
- HTPPS请求 证书 解决方案
- 计算机文化学习笔记2
- MySQL 视图