zoukankan      html  css  js  c++  java
  • Redis分布式锁

      提起来锁,可能第一个念头就是在想是不是要使用 synchronized。但是synchronized一般都是使用在一个服务器当中。

      当多个服务器的时候该如何使用,能否保证锁住的东西起作用吗?

      锁,很显而易见,就是需要排队去解决,开锁解锁。

    一. 思考

      按照这个思路,那么分布式锁是不是也是一样,锁定某个东西,在另一个地方使用完成以后解开。在重新回归使用?只不过和synchronized区分的是单服务器和多服务器罢了

    二. 开始进行测验

      首先先进行库存小项目分析

      1. 正常不加锁情况

    ·  

     1     /**
     2      * 测试Redis分布式锁
     3      */
     4     public void simulation(){
     5         //入库存20件
     6         redisTemplate.opsForValue().set(GOODS,20);
     7         /**
     8          * 模拟不同人数购买
     9          */
    10         for (int i=0;i<20;i++){
    11             //单数的测试
    12             int amount = i%3+1;
    13             new Thread(()->unlock(amount)).start();
    14         }
    15     }
    16 
    17 
    18    public void unlock(int goodsStorage){
    19         //获取线程名
    20         String name = Thread.currentThread().getName();
    21         //获取库存数量
    22         Integer num = Integer.parseInt(String.valueOf(redisTemplate.opsForValue().get(GOODS)));
    23         //库存大于需求
    24         if (num>=goodsStorage){
    25             //剩余量
    26             Long decrement = redisTemplate.opsForValue().decrement(GOODS, goodsStorage);
    27             System.out.println(name+"购买后剩余--->"+decrement);
    28         }else {
    29             System.out.println(name+"库存不足,请稍后联系补货!");
    30         }
    31     }

    出现卖超了的情况。

      2.单服务器情况下,增加synchronized

     1  public synchronized void unlock(int goodsStorage){
     2         //获取线程名
     3         String name = Thread.currentThread().getName();
     4         //获取库存数量
     5         Integer num = Integer.parseInt(String.valueOf(redisTemplate.opsForValue().get(GOODS)));
     6         //库存大于需求
     7         if (num>=goodsStorage){
     8             //剩余量
     9             Long decrement = redisTemplate.opsForValue().decrement(GOODS, goodsStorage);
    10             System.out.println(name+"购买后剩余--->"+decrement);
    11         }else {
    12             System.out.println(name+"库存不足,请稍后联系补货!");
    13         }
    14     }

    发现货物并不会出现卖超出的情况发现,但是多个服务器上发现还是会出现问题

      3. 增加Redis分布式锁(在分布式情况下)

     1    public void plusLock(int goodsStorage){
     2         //线程名
     3         String name = Thread.currentThread().getName();
     4         //判断是否存在锁
     5         //这一步的问题是解决在设置完锁以后,在还没有设置过期时间之前而出现问题
     6         final Boolean redisLock =   redisTemplate.opsForValue().setIfAbsent(LOCK,name,3,TimeUnit.SECONDS);
     7         if (redisLock){
     8             //查看剩余多少库存
     9             int num = Integer.parseInt(String.valueOf(redisTemplate.opsForValue().get(GOODS)));
    10             //库存大于购买
    11             if (num>=goodsStorage){
    12                 Long decrement = redisTemplate.opsForValue().decrement(GOODS, goodsStorage);
    13                 System.out.println(name+"购买后剩余:"+decrement);
    14             }else {
    15                 System.out.println("不好意思,库存不足");
    16             }
    17             //释放锁
    18             redisTemplate.delete(LOCK);
    19         }else {
    20             System.out.println("不好意思,请重新抢锁");
    21         }
    22     }

    宁愿会有人没有买到,也不要库存超出,因为一般没有买到会出现重复点击

    分布式锁个人理解 :

       从房东租客传递钥匙变成了物业统一帮租客管理钥匙。

      

  • 相关阅读:
    Linux运维工程师需要掌握什么才能胜任工作呢
    我眼中的Linux系统和红帽RHCE认证
    Linux系统从零到高手的进阶心得
    我在大学毕业后学习Linux系统的心得经验
    装RAC跑脚本报错
    Oracle rac11g 安装报INS41112
    Oracle升级11.2.0.3-11.2.0.4(Windows)
    防存储掉线安装监控软件
    跨平台迁移数据库windows-Linux
    linux crontab -e生成日期格式
  • 原文地址:https://www.cnblogs.com/honour1207/p/14418283.html
Copyright © 2011-2022 走看看