Redis 分布式锁及缓存注释的使用方法
使用工具:Apache an
测压命令: ab -n 100 -c 100 http://www.baidu.com -n代表模拟100个请求,-c代表模拟100个并发,相当于100个人同时访问
ab -t 60 -c 100 http://www.baidu.com 60秒100个并发,不断发送请求
并发处理:
1.加synchronized锁单线程处理、缺点: 无法做到细粒度控制 只适合单点的情况 同时运行内存缓慢,效率低(出现等待情况)
2.redis分布式锁:
可以支撑每秒10多万的并发,支持分布式,可以更细粒的控制代码(多台机器上多个线程对一个数据进行操作的互斥)
SETNX key value
将key设置值为value,如果key不存在,这种情况下等同于SET命令,当key存在时,什么也不做
GETSET key value
自动将key对应到value并且返回原来key和对应的value. 如果key存在但是对应的value不是字符串,就返回错误
DEMO演示:
加锁处理方法:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
@Component@Slf4jpublic class RedisLock { @Autowired private StringRedisTemplate stringRedisTemplate; //加锁 /* * @param key id * @param value 当前时间+超时时间 * * */ public boolean lock(String key,String value){ if (stringRedisTemplate.opsForValue().setIfAbsent(key,value)){ return true;//加锁成功就返回true } //不加下面这个可能出现死锁情况 //代码value加了过期时间* @param value 当前时间+超时时间
//获取上一个锁的时间,并判断是否小于当前时间,小于就下一步判断,就返回true加锁成功
String currentValue=stringRedisTemplate.opsForValue().get(key); //如果锁过期 if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue)<System.currentTimeMillis()){ //存储时间要小于当前时间 //出现死锁的另一种情况,当多个线程进来后都没有返回true,接着往下执行,执行代码有先后,而if判断里只有一个线程才能满足条件
//oldValue=currentValue
//多个线程进来后只有其中一个线程能拿到锁(即oldValue=currentValue),其他的返回false
String oldValue=stringRedisTemplate.opsForValue().getAndSet(key,value); if (!StringUtils.isEmpty(oldValue)&& oldValue.equals(currentValue)){//上一个时间不为空,并且等于当前时间 return true; } } return false;//失败返回false } //解锁 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); } }} |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
//秒杀demopprivate static final int TIMEOUT=10*1000;//超时时间设置为10s@Autowriteprivate RedisLock redisLock;public void method(String id){//加锁-死锁出现:即在加锁后运行程序出现意外报了异常,而此时还没调用解锁方法//那么在下一个线程调用加锁方法是就不能set,直接返回fale,然后一直停留在加锁失败状态 这就出现了死锁
long time=System.currentTimeMillis()+TIMEOUT;//如果加锁不成功就抛出异常 if(!redisLock.lock.get(id,String.valueof(time))){throw new WechatSellException(101,"哎哟喂,人也太多了,换个姿势再试试");}//加锁成功就实现业务代码处理//1.查询该商品库存,为0表示活动结束//2.下单3.扣库存//解锁redisLock.unlock(id,String.valueof(time)));} |
Redis 分布式锁及缓存注释的使用方法的更多相关文章
- SpringBoot集成Redis分布式锁以及Redis缓存
https://blog.csdn.net/qq_26525215/article/details/79182687 集成Redis 首先在pom.xml中加入需要的redis依赖和缓存依赖 < ...
- SpringBoot集成Redis 一 分布式锁 与 缓存
1.添加依赖及配置(application.yml) <!-- 引入redis依赖 --> <dependency> <groupId>org.springfram ...
- 【分布式缓存系列】集群环境下Redis分布式锁的正确姿势
一.前言 在上一篇文章中,已经介绍了基于Redis实现分布式锁的正确姿势,但是上篇文章存在一定的缺陷——它加锁只作用在一个Redis节点上,如果通过sentinel保证高可用,如果master节点由于 ...
- Redis分布式锁---完美实现
这几天在做项目缓存时候,因为是分布式的所以需要加锁,就用到了Redis锁,正好从网上发现两篇非常棒的文章,来和大家分享一下. 第一篇是简单完美的实现,第二篇是用到的Redisson. Redis分布式 ...
- 面试官:你真的了解Redis分布式锁吗?
什么是分布式锁 说到Redis,我们第一想到的功能就是可以缓存数据,除此之外,Redis因为单进程.性能高的特点,它还经常被用于做分布式锁. 锁我们都知道,在程序中的作用就是同步工具,保证共享资源在同 ...
- Redis分布式锁 (图解-秒懂-史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
- Redis分布式锁
Redis分布式锁 分布式锁是许多环境中非常有用的原语,其中不同的进程必须以相互排斥的方式与共享资源一起运行. 有许多图书馆和博客文章描述了如何使用Redis实现DLM(分布式锁管理器),但是每个库都 ...
- redis分布式锁和消息队列
最近博主在看redis的时候发现了两种redis使用方式,与之前redis作为缓存不同,利用的是redis可设置key的有效时间和redis的BRPOP命令. 分布式锁 由于目前一些编程语言,如PHP ...
- redis咋么实现分布式锁,redis分布式锁的实现方式,redis做分布式锁 积极正义的少年
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
随机推荐
- VS Code插件配置
常用 VS Code 插件: Auto Import 有了这个插件,就不需要再手动引入文件了.如果是基于组件的项目,直接输入组件名插件会自动处理 imported. ** Add jsdoc comm ...
- 工具类封装之--BaseController
package cn.xxx.base; import cn.xxx.gecustomer.beans.GeCustomer; import cn.xxx.gecustomer.beans.GeCus ...
- 比NPOI更好用的Excel操作库——EPPlus
提到通过纯.Net读写Excel,一般首先想到的自然是大名鼎鼎的NPOI,就连微软官方的MSDN都有专门的一篇文章来介绍它的用法.今天在一个项目中使用到了导出报表为Excel的功能,便特地的试用了一下 ...
- canvas 经典播放器图标
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- angular + socket.io+nodejs
一.服务器端: 基本和nodejs工程相同 https://www.cnblogs.com/xuanmanstein/p/10509445.html 安装socket.io npm i --save ...
- (转)关于request.getServletPath(),request.getContextPath()的总结
文章完全转载自 : https://blog.csdn.net/qq_27770257/article/details/79438987 最近对于request中的几种“路径”有点混淆,查找网上资源都 ...
- Ubuntu 16.04安装httpd
1.下载httpd源码(当前版本为2.4.37) http://httpd.apache.org/download.cgi 2.解压编译 tar -zxf httpd-2.4.37.tar.gzcd ...
- Jmeter转换成中文模式
本片文章转至:https://blog.csdn.net/him2014/article/details/79603887 下载安装好Jmeter后默认的是英文,对于我这种学渣来说简直就是受到了100 ...
- C#流程控制语句--分支语句(if,switch,三位运算符)
分支语句:判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的). 分支语句 if if(判断条件表达式) {//表达式结果为tu ...
- React文档(二十三)Web Components
React和web components是为了解决不同问题而创立的.web components为可重用组件提供了健壮的封装,而React提供了声明式的库来保持DOM和数据同步.这两点是互相补充的.作 ...