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实现分布式锁.虽然网上已经有各种介 ...
随机推荐
- H5外包团队 MUI文档技术资料大全
HTML5+ API缓存:http://www.dcloud.io/docs/api/zh_cn/cache.html h.js:http://www.hcoder.net/h vue.js:http ...
- Foxmail设置IMAP和STMP服务器
- (6)tcp-socket
(1)client端口: import socket# 产生一个socket对象sk = socket.socket()# 建立连接sk.connect( ("127.0.0.1" ...
- Java8:Lambda表达式增强版Comparator和排序
1.概述 在这篇教程里,我们将要去了解下即将到来的JDK 8(译注,现在JDK 8已经发布了)中的Lambda表达式——特别是怎样使用它来编写Comparator和对集合(Collection)进行排 ...
- 雷林鹏分享:jQuery EasyUI 数据网格 - 设置冻结列
jQuery EasyUI 数据网格 - 设置冻结列 本实例演示如何冻结一些列,当用户在网格上移动水平滚动条时,冻结列不能滚动到视图的外部. 为了冻结列,您需要定义 frozenColumns 属性. ...
- 关于spark写入文件至文件系统并制定文件名之自定义outputFormat
引言: spark项目中通常我们需要将我们处理之后数据保存到文件中,比如将处理之后的RDD保存到hdfs上指定的目录中,亦或是保存在本地 spark保存文件: 1.rdd.saveAsTextFile ...
- es6中promise ALL Race Resolve Reject finish的实现
function mypromise(func){ this.statue = "pending"; this.data = null; this.resolveCallback ...
- class类初始化之后调用赋值问题记录
class PWSTRDELL: def __init__(self, pw_str):#该方法在类实例化时会自动调用 self.pw = pw_str self.strength_level = 0 ...
- Codeforces Round #129 (Div. 1)E. Little Elephant and Strings
题意:有n个串,询问每个串有多少子串在n个串中出现了至少k次. 题解:sam,每个节点开一个set维护该节点的字符串有哪几个串,启发式合并set,然后在sam上走一遍该串,对于每个可行的串,所有的fa ...
- 使用Visual Studio Installer 2015打包WPF程序
前言 做过WPF项目,就少不了要将程序打包部署到客户现场,因为一般长时间不会更新打包程序,每次变动较大需要重新配置打包程序时,就会有些生疏,不那么得心应手.为了方便记忆,记录到博客中. 准备 因为做过 ...