使用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分布式锁用法的更多相关文章

  1. Redis分布式锁的原理和实现

    前言 我们之前聊过redis的,对基础不了解的可以移步查看一下: 几分钟搞定redis存储session共享--设计实现:https://www.cnblogs.com/xiongze520/p/10 ...

  2. redis分布式锁和消息队列

    最近博主在看redis的时候发现了两种redis使用方式,与之前redis作为缓存不同,利用的是redis可设置key的有效时间和redis的BRPOP命令. 分布式锁 由于目前一些编程语言,如PHP ...

  3. Redis分布式锁的try-with-resources实现

    Redis分布式锁的try-with-resources实现 一.简介 在当今这个时代,单体应用(standalone)已经很少了,java提供的synchronized已经不能满足需求,大家自然 而 ...

  4. 关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁

    首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...

  5. Redlock:Redis分布式锁最牛逼的实现

    普通实现 说道Redis分布式锁大部分人都会想到:setnx+lua,或者知道set key value px milliseconds nx.后一种方式的核心实现命令如下: - 获取锁(unique ...

  6. $.ajax()方法详解 ajax之async属性 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )

    $.ajax()方法详解   jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Str ...

  7. 五分钟DBA:浅谈伪分布式数据库架构

    [IT168 技术]12月25日消息,2010互联网行业技术研讨峰会今日在上海华东理工大学召开.本次峰会以“互联网行业应用最佳实践”为主题,定位于互联网架构设计.应用开发.应用运维管理,同时,峰会邀请 ...

  8. 面试官:你真的了解Redis分布式锁吗?

    什么是分布式锁 说到Redis,我们第一想到的功能就是可以缓存数据,除此之外,Redis因为单进程.性能高的特点,它还经常被用于做分布式锁. 锁我们都知道,在程序中的作用就是同步工具,保证共享资源在同 ...

  9. Redis分布式锁升级版RedLock及SpringBoot实现

    分布式锁概览 在多线程的环境下,为了保证一个代码块在同一时间只能由一个线程访问,Java中我们一般可以使用synchronized语法和ReetrantLock去保证,这实际上是本地锁的方式.但是现在 ...

随机推荐

  1. Ajax中Put和Delete请求传递参数无效的解决方法(Restful风格)

    本文装载自:http://blog.csdn.net/u012737182/article/details/52831008    感谢原文作者分享 开发环境:Tomcat9.0 在使用Ajax实现R ...

  2. 【DVWA】Command Injection(命令注入)通关教程

    日期:2019-08-01 16:05:34 更新: 作者:Bay0net 介绍:利用命令注入,来复习了一下绕过过滤的方法,还可以写一个字典来 fuzz 命令注入的点. 0x01. 漏洞介绍 仅仅需要 ...

  3. Hibernate初了解

    Hibernate是一个开放源代码的对象关系映射框架, 它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JD ...

  4. IDEA和VS快捷键对比

    IDEA和Visual Studio快捷键对比 VS     F5 F9            resume programe 恢复程序     Alt+F10       show executio ...

  5. Alias sample(别名采样)

    应用场景:加权采样,即按照随机事件出现的概率抽样 具体算法: 举例如上,随机事件出现的概率依次是1/2,1/3,1/12,1/12;记随机事件的个数为N,则所有事件概率乘以N后概率为2,4/3,1/3 ...

  6. 20191224 Spring官方文档(启动)

    再学Spring 之前看过Spring教学视频,看过<Spring5高级编程>,但是对于Spring始终还是感觉差了一点,应该是底层没有学好,这次再学Spring,就是要将Spring底层 ...

  7. 在SQL Server 中创建外键

    建外键的前提是此外键必须是另外一个表的主键. 建外键的步骤: 第一步打开要建外键表的设计器,右击选择“关系”. 然后弹出“外键关系”窗体,我们选择“添加”,然后点击“表和列规范”后面的小按钮, 就会弹 ...

  8. awk 命令使用指南

    一:awk 的执行流程 (1) 首先执行BEGIN{} 块中的初始化操作 (2) 然后从指定的数据文件中循环读取一个数据行 ( 自动更新 NF.NR.$0.$1....., 等内建变量的值) (3) ...

  9. Spring(三)--Spring bean的生命周期

    Spring bean的生命周期 ApplicationContext Bean生命周期流程 1.需要的实体类 ackage com.xdf.bean; import org.springframew ...

  10. 【6.18校内test】T3细胞分裂

    尽管T1T2很简单,但还是阻止不了我T3wa一片 细胞分裂[题目链接] xcg同学有一个80pts的代码 他说他的代码和我的很像,可惜我比较笨,只有30pts 其实这道题考场上是想到要分解质因数了,然 ...