使用工具: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
@Slf4j
public 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
//秒杀demo
pprivate static final int TIMEOUT=10*1000;//超时时间设置为10s
@Autowrite
private 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 分布式锁及缓存注释的使用方法的更多相关文章

  1. SpringBoot集成Redis分布式锁以及Redis缓存

    https://blog.csdn.net/qq_26525215/article/details/79182687 集成Redis 首先在pom.xml中加入需要的redis依赖和缓存依赖 < ...

  2. SpringBoot集成Redis 一 分布式锁 与 缓存

    1.添加依赖及配置(application.yml) <!-- 引入redis依赖 --> <dependency> <groupId>org.springfram ...

  3. 【分布式缓存系列】集群环境下Redis分布式锁的正确姿势

    一.前言 在上一篇文章中,已经介绍了基于Redis实现分布式锁的正确姿势,但是上篇文章存在一定的缺陷——它加锁只作用在一个Redis节点上,如果通过sentinel保证高可用,如果master节点由于 ...

  4. Redis分布式锁---完美实现

    这几天在做项目缓存时候,因为是分布式的所以需要加锁,就用到了Redis锁,正好从网上发现两篇非常棒的文章,来和大家分享一下. 第一篇是简单完美的实现,第二篇是用到的Redisson. Redis分布式 ...

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

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

  6. Redis分布式锁 (图解-秒懂-史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

  7. Redis分布式锁

    Redis分布式锁 分布式锁是许多环境中非常有用的原语,其中不同的进程必须以相互排斥的方式与共享资源一起运行. 有许多图书馆和博客文章描述了如何使用Redis实现DLM(分布式锁管理器),但是每个库都 ...

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

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

  9. redis咋么实现分布式锁,redis分布式锁的实现方式,redis做分布式锁 积极正义的少年

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

随机推荐

  1. Vue-admin工作整理(九): 状态管理Vuex-state和getters

    前提:通过项目结构个人设置创建的项目 store文件下actions.js.mutations.js.state.js都是根级别的状态管理,引用入口是通过index.js来实现,整个Vuex处理逻辑为 ...

  2. 根据不同浏览器判断OCX插件是否安装

    最近项目进入到了验收阶段,需要兼容不同的浏览器,海康的Demo写了一个判断插件是否成功安装的函数,但是经过测试,只在IE浏览器下有效果,在其他的浏览器下面会出现Bug,现在需要写一个通用的方法,在不同 ...

  3. vue admin mock数据

    搭建脚手架axios访问不到接口:mock数据的问题mock下的index.js设置了默认指向

  4. Java /C# 实现文件压缩

    纯粹为了记录. 参考了 https://www.cnblogs.com/zeng1994/p/7862288.html import java.util.List; import java.util. ...

  5. C++之标准库vector

    目录 1.成员函数 2.元素访问 3.迭代器iterator 4.容量capacity 5.修改函数 std::vector是一个封装动态数组的序列容器 std::pmr::vector是一个使用多态 ...

  6. Web程序报错:Error instantiating servlet

    ---恢复内容开始--- web程序的前期准备工作都做好了,也就是web程序的目录都建好了,在WEB-INF文件夹下建立了classes文件夹,用于存放编好的.class文件.我想这两个类应该都在相应 ...

  7. HIT2019春软件构造->重写hashCode()方法

    不需要重写equals方法: 1.     一个类的每一个实例本质上都是唯一的. 2.     不关心一个类是否提供了“逻辑相等”的测试功能 3.     超类已经改写了equals方法,并且从超类继 ...

  8. java 使用GET请求编码问题解决

    java GET请求解决编码的有效代码前端: encodeURI(encodeURI("你好") 后端代码: String name = request.getParameter( ...

  9. jq里验证插件的自定义方法Jquery.validator.addMethod()示例

    最近写验证的时候感觉原生的验证谢了一遍又一遍,就想到了“不要重复造轮子,学会管理自己的工具库”这句名言,于是尝试用jq的validator. 用过又发现需要自定义方法去验证,于是去查官网,写了Jque ...

  10. docker 容器的mysql主从复制

    一. 1.首先拉取docker镜像,我们这里使用5.7版本的mysql:   docker pull mysql:5.7 2.分别启动主从两个容器: docker run -p 3339:3306 - ...