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     }

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

    分布式锁个人理解 :

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

      

  • 相关阅读:
    leetcode Convert Sorted List to Binary Search Tree
    leetcode Convert Sorted Array to Binary Search Tree
    leetcode Binary Tree Level Order Traversal II
    leetcode Construct Binary Tree from Preorder and Inorder Traversal
    leetcode[105] Construct Binary Tree from Inorder and Postorder Traversal
    证明中序遍历O(n)
    leetcode Maximum Depth of Binary Tree
    限制 button 在 3 秒内不可重复点击
    HTML 和 CSS 画三角形和画多边行基本原理及实践
    在线前端 JS 或 HTML 或 CSS 编写 Demo 处 JSbin 与 jsFiddle 比较
  • 原文地址:https://www.cnblogs.com/honour1207/p/14418283.html
Copyright © 2011-2022 走看看