浅谈redis分布式锁用法
使用redis的setnx命令进行实现
@Component
@Slf4j
public class RedisLock {
@Autowired
private StringRedisTemplate stringRedisTemplate; /**
* 加锁
*
* @param key
* @param value
* @return
*/
public boolean lock(String key, String value) {
if (stringRedisTemplate.opsForValue().setIfAbsent(key, value)) {
return true;
}
String currentValue = stringRedisTemplate.opsForValue().get(key);
//防止死锁
if (!StringUtils.isEmpty(currentValue)
&& Long.parseLong(currentValue) < System.currentTimeMillis()) {
String oldValue = stringRedisTemplate.opsForValue().getAndSet(key, value);
if (!StringUtils.isEmpty(oldValue)
&& oldValue.equals(currentValue)) {
return true;
} }
return false;
} /**
* 解锁
* @param key
* @param value
*/
public void unlock(String key, String value) {
try {
String currentValue = stringRedisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(currentValue)
&& currentValue.equals(value)) {
stringRedisTemplate.opsForValue().getOperations().delete(key);
}
} catch (Exception e) {
log.error("【redis分布式锁】 解锁异常,{}", e);
} }
}
demo
@Service
public class SecKillServiceImpl implements SeckillService {
//超时时间10秒
private static final int TIMEOUT = 10 * 1000;
@Autowired
private RedisLock redisLock; static Map<String, Integer> products;
static Map<String, Integer> stock;
static Map<String, String> orders; {
products = new HashMap<>();
stock = new HashMap<>();
orders = new HashMap<>();
products.put("123456", 100000);
stock.put("123456", 100000);
} private String queryMap(String productId) {
return "国庆活动,皮蛋粥特价,限量份"
+ products.get(productId)
+ "还剩:" + stock.get(productId) + "份"
+ "该商品成功下单用户数目:"
+ orders.size() + "人";
} @Override
public void orderProductMockDiffUser(String productId) {
Long time = System.currentTimeMillis() + TIMEOUT;
//加锁
if (!redisLock.lock(productId, String.valueOf(time))) {
throw new SellException(101, "哎呦喂,人也太多了,在试试");
} Integer stockNum = stock.get(productId);
if (stockNum == 0) {
throw new SellException(100, "活动结束");
} else {
//下单
orders.put(KeyUtil.genUniqueKey(), productId);
//减库存
stockNum = stockNum - 1;
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
stock.put(productId, stockNum);
}
//解锁
redisLock.unlock(productId, String.valueOf(time));
} @Override
public String querySecKillProductInfo(String productId) {
return queryMap(productId);
}
}
浅谈redis分布式锁用法的更多相关文章
- Redis分布式锁的原理和实现
前言 我们之前聊过redis的,对基础不了解的可以移步查看一下: 几分钟搞定redis存储session共享--设计实现:https://www.cnblogs.com/xiongze520/p/10 ...
- redis分布式锁和消息队列
最近博主在看redis的时候发现了两种redis使用方式,与之前redis作为缓存不同,利用的是redis可设置key的有效时间和redis的BRPOP命令. 分布式锁 由于目前一些编程语言,如PHP ...
- Redis分布式锁的try-with-resources实现
Redis分布式锁的try-with-resources实现 一.简介 在当今这个时代,单体应用(standalone)已经很少了,java提供的synchronized已经不能满足需求,大家自然 而 ...
- 关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁
首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...
- Redlock:Redis分布式锁最牛逼的实现
普通实现 说道Redis分布式锁大部分人都会想到:setnx+lua,或者知道set key value px milliseconds nx.后一种方式的核心实现命令如下: - 获取锁(unique ...
- $.ajax()方法详解 ajax之async属性 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )
$.ajax()方法详解 jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Str ...
- 五分钟DBA:浅谈伪分布式数据库架构
[IT168 技术]12月25日消息,2010互联网行业技术研讨峰会今日在上海华东理工大学召开.本次峰会以“互联网行业应用最佳实践”为主题,定位于互联网架构设计.应用开发.应用运维管理,同时,峰会邀请 ...
- 面试官:你真的了解Redis分布式锁吗?
什么是分布式锁 说到Redis,我们第一想到的功能就是可以缓存数据,除此之外,Redis因为单进程.性能高的特点,它还经常被用于做分布式锁. 锁我们都知道,在程序中的作用就是同步工具,保证共享资源在同 ...
- Redis分布式锁升级版RedLock及SpringBoot实现
分布式锁概览 在多线程的环境下,为了保证一个代码块在同一时间只能由一个线程访问,Java中我们一般可以使用synchronized语法和ReetrantLock去保证,这实际上是本地锁的方式.但是现在 ...
随机推荐
- Ajax中Put和Delete请求传递参数无效的解决方法(Restful风格)
本文装载自:http://blog.csdn.net/u012737182/article/details/52831008 感谢原文作者分享 开发环境:Tomcat9.0 在使用Ajax实现R ...
- 【DVWA】Command Injection(命令注入)通关教程
日期:2019-08-01 16:05:34 更新: 作者:Bay0net 介绍:利用命令注入,来复习了一下绕过过滤的方法,还可以写一个字典来 fuzz 命令注入的点. 0x01. 漏洞介绍 仅仅需要 ...
- Hibernate初了解
Hibernate是一个开放源代码的对象关系映射框架, 它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JD ...
- IDEA和VS快捷键对比
IDEA和Visual Studio快捷键对比 VS F5 F9 resume programe 恢复程序 Alt+F10 show executio ...
- Alias sample(别名采样)
应用场景:加权采样,即按照随机事件出现的概率抽样 具体算法: 举例如上,随机事件出现的概率依次是1/2,1/3,1/12,1/12;记随机事件的个数为N,则所有事件概率乘以N后概率为2,4/3,1/3 ...
- 20191224 Spring官方文档(启动)
再学Spring 之前看过Spring教学视频,看过<Spring5高级编程>,但是对于Spring始终还是感觉差了一点,应该是底层没有学好,这次再学Spring,就是要将Spring底层 ...
- 在SQL Server 中创建外键
建外键的前提是此外键必须是另外一个表的主键. 建外键的步骤: 第一步打开要建外键表的设计器,右击选择“关系”. 然后弹出“外键关系”窗体,我们选择“添加”,然后点击“表和列规范”后面的小按钮, 就会弹 ...
- awk 命令使用指南
一:awk 的执行流程 (1) 首先执行BEGIN{} 块中的初始化操作 (2) 然后从指定的数据文件中循环读取一个数据行 ( 自动更新 NF.NR.$0.$1....., 等内建变量的值) (3) ...
- Spring(三)--Spring bean的生命周期
Spring bean的生命周期 ApplicationContext Bean生命周期流程 1.需要的实体类 ackage com.xdf.bean; import org.springframew ...
- 【6.18校内test】T3细胞分裂
尽管T1T2很简单,但还是阻止不了我T3wa一片 细胞分裂[题目链接] xcg同学有一个80pts的代码 他说他的代码和我的很像,可惜我比较笨,只有30pts 其实这道题考场上是想到要分解质因数了,然 ...