<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Redis分布式鎖

      redis1.0版本的鎖(有bug版本的分布式鎖)
          @GetMapping("/Redis1/{id}")
          public String RedisLock1(@PathVariable("id") String id){
              String LockName="LockName";
              Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent(LockName, "shuxiaosheng",10,TimeUnit.SECONDS);
              if (lock!=null&&!lock){
                  return "系統繁忙,請稍微再試";
              }
              try {
                  Integer stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));
                  if (stock>0){
                      Integer realStock=stock-1;
                      stringRedisTemplate.opsForValue().set("stock",realStock.toString());
                  }
              }finally{
                  stringRedisTemplate.delete(LockName);
              }
              return "end";
      
          }
      

      模擬因處理業務時間過長而導致的分布式鎖失效的情況

          @GetMapping("/Redis1/{id}")
          public String RedisLock1Exception(@PathVariable("id") Integer id) throws Exception{
              String LockName="LockName";
              Boolean shuxiaosheng = stringRedisTemplate.opsForValue().setIfAbsent(LockName, "線程"+id,10,TimeUnit.SECONDS);
              if (shuxiaosheng!=null&&!shuxiaosheng){
                  return "系統繁忙,請稍微再試";
              }
              try {
                  //線程暫停超過十秒,鎖就自動釋放了
                  if(1==id){
                      Thread.sleep(15000);
                      System.out.println("線程1暫停15秒,鎖已經自動釋放");
                  }
                  if(2==id){
                      Thread.sleep(8000);
                      System.out.println("線程2暫停8秒");
                  }
                  Integer stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));
                  if (stock>0){
                      Integer realStock=stock-1;
                      stringRedisTemplate.opsForValue().set("stock",realStock.toString());
                  }
              }finally{
                  System.out.println("當前線程是:"+id+"釋放的鎖是:"+stringRedisTemplate.opsForValue().get(LockName));
                  stringRedisTemplate.delete(LockName);
              }
              return "end";
      
          }
      
      1.0版本的存在的缺陷,例如:
      1. 當線程1進來,執行業務代碼需要15秒.
      2. 當線程2進來,執行業務代碼需要8秒.
      3. 線程1最先進來,拿到了鎖,當線程1執行業務代碼到11秒時,鎖被自動釋放了.
      4. 線程2立馬進來,拿到了鎖,當線程2執行業務代碼到4秒時,這時,線程1業務代碼已經執行結束,并且手動釋放了線程2加的鎖,
      控制臺打印
      線程1暫停15秒,鎖已經自動釋放
      當前線程是:1釋放的鎖是:線程2
      線程2暫停8秒
      當前線程是:2釋放的鎖是:null
      
      總結:

      因為高并發,線程1執行業務的代碼時間大于鎖超時時間,線程1的鎖自動釋放了,線程2加入進來,結果線程1執行完畢,釋放了線程2加的鎖,出現問題

      redis2.0版本的鎖(適用于并發一般的軟件公司)
          @GetMapping("/Redis2/{id}")
          public String RedisLock12(@PathVariable("id") Integer id) throws Exception{
              String LockName="LockName";
              String uuid = UUID.randomUUID().toString();
              Boolean shuxiaosheng = stringRedisTemplate.opsForValue().setIfAbsent(LockName, uuid+"線程"+id,10,TimeUnit.SECONDS);
              if (shuxiaosheng!=null&&!shuxiaosheng){
                  return "系統繁忙,請稍微再試";
              }
              try {
                  //線程暫停十秒,鎖就自動釋放了
                  if(1==id){
                      Thread.sleep(15000);
                      System.out.println("線程1暫停15秒,鎖已經自動釋放");
                  }
                  if(2==id){
                      Thread.sleep(8000);
                      System.out.println("線程2暫停8秒");
                  }
                  Integer stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));
                  if (stock>0){
                      Integer realStock=stock-1;
                      stringRedisTemplate.opsForValue().set("stock",realStock.toString());
                  }
              }finally{
                  //當前線程只能釋放自己加的鎖
                  if ((uuid+"線程"+id).equals(stringRedisTemplate.opsForValue().get(LockName))){
                      System.out.println("當前線程是:"+id+"釋放的鎖是:"+stringRedisTemplate.opsForValue().get(LockName));
                      stringRedisTemplate.delete(LockName);
                  }
      
              }
              return "end";
      
          }
      
      控制臺打印
      線程1暫停15秒,鎖已經自動釋放
      線程2暫停8秒
      當前線程是:2釋放的鎖是:c579e42a-ecfb-40a4-8e5f-689f3d858f40線程2
      
      總結

      redis2.0相比較與redis1.0,就加了個核心判斷,當前線程只能釋放自己加的鎖,不能釋放別人的鎖

      到此簡單的redis鎖就已經實現了

      redis3.0版本的鎖(適用并發比較高互聯網公司)
      添加依賴
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-data-redis</artifactId>
                  <version>2.4.1</version>
                  <exclusions>
                      <exclusion>
                          <groupId>io.lettuce</groupId>
                          <artifactId>lettuce-core</artifactId>
                      </exclusion>
                  </exclusions>
              </dependency>
              <dependency>
                  <groupId>redis.clients</groupId>
                  <artifactId>jedis</artifactId>
                  <version>3.3.0</version>
              </dependency>
              <dependency>
                  <groupId>org.redisson</groupId>
                  <artifactId>redisson-spring-boot-starter</artifactId>
                  <version>3.13.6</version>
              </dependency>
      
      添加配合類
      @Configuration
      public class MyRedissonConfig {
      
          @Bean(destroyMethod="shutdown")
          RedissonClient redisson() throws IOException {
              //1、創建配置
              Config config = new Config();
              config.useSingleServer()
                      .setAddress("127.0.0.1:6379");
              return Redisson.create(config);
          }
          
      }
      
      實現
       @RequestMapping("/redisson")
          public String testRedisson(){
              //獲取分布式鎖,只要鎖的名字一樣,就是同一把鎖
              RLock lock = redissonClient.getLock("lock");
      
              //加鎖(阻塞等待),默認過期時間是30秒
              lock.lock();
              try{
                  //如果業務執行過長,Redisson會自動給鎖續期
                  Thread.sleep(1000);
                  System.out.println("加鎖成功,執行業務邏輯");
              } catch (InterruptedException e) {
                  e.printStackTrace();
              } finally {
                  //解鎖,如果業務執行完成,就不會繼續續期,即使沒有手動釋放鎖,在30秒過后,也會釋放鎖
                  lock.unlock();
              }
      
              return "Hello Redisson!";
          }
      
      原理

      大家都知道,如果剛上完鎖,負責存儲這個分布式的Redisson節點宕機后,這樣就出現了死鎖,為了避免這種情況發生,Redisson內部提供了一個監控鎖的看門狗,他的作用是:如果當前線程還有持有鎖,且鎖快要到期了(默認鎖是30秒),就繼續延長鎖的時間,如果當前線程掛了,那么就不會自動延長鎖,到期之后,鎖會自動釋放

      posted on 2021-07-09 14:30  疏小勝  閱讀(54)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 人妻少妇乱子伦精品无码专区电影| 婷婷六月色| 少妇上班人妻精品偷人| 欧美乱人伦人妻中文字幕| 国产农村激情免费专区| 激情综合网激情五月伊人| 国产一精品一av一免费| 国产成人一区二区不卡| 国产三级国产精品久久成人| 国产精品二区中文字幕| 国产95在线 | 欧美| 久久精品久久黄色片看看| 亚洲人成网站18禁止无码| 亚洲欧美国产免费综合视频| 性欧美欧美巨大69| 亚洲综合精品第一页| 邹平县| 欧美变态另类牲交| 亚洲偷自拍国综合| 午夜福利视频| 麻豆亚州无矿码专区视频| 人妻少妇偷人无码视频| 柳州市| 特级做a爰片毛片免费看无码| 乱人伦中文字幕成人网站在线| 台安县| 国产女人在线视频| 成人影片麻豆国产影片免费观看| 国产国拍亚洲精品永久软件| 越南毛茸茸的少妇| 精品人妻无码中文字幕在线| 中文字幕久久国产精品| 性一交一乱一乱一视频| 在线中文字幕第一页| 国内不卡一区二区三区| 亚洲高清国产拍精品熟女| 亚洲一区二区在线无码| 国产成人亚洲欧美二区综合| 91色老久久精品偷偷蜜臀| 999福利激情视频| 麻豆一区二区中文字幕|