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

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

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

      如何實(shí)現(xiàn)分布式鎖?

      什么是分布式鎖?

      既然是是分布式鎖,那么肯定是用在多個(gè)進(jìn)程之間甚至是多個(gè)物理機(jī)之間,因?yàn)樵诤芏鄨鼍爸形覀円WC這個(gè)數(shù)據(jù)的一致性,也就是說這么多的進(jìn)程,我必須保證在同一時(shí)刻只能有一個(gè)線程在執(zhí)行,這樣的情景在一個(gè)進(jìn)程內(nèi)很好解決,我們可以使用Java給我們提供的各種鎖、比如說,Synchronized、ReentrantLock、ReadWriteLock等,但是在多進(jìn)程條件下這些鎖就不太適用了,比如說在電商系統(tǒng)的訂單業(yè)務(wù)模塊這個(gè)業(yè)務(wù)模塊某一項(xiàng)功能是定時(shí)的將沒有支付的訂單給取消掉,同時(shí)商品的庫存加上訂單里面該商品的數(shù)量,加入這個(gè)模塊是集群部署的,那么該如何保證某一時(shí)間只有一個(gè)在執(zhí)行呢?負(fù)責(zé)就會出現(xiàn)數(shù)據(jù)錯(cuò)亂的傾情況,這我們就必須借助于其他第三方工具比如Redis、Zookeeper、mysql,因?yàn)檫@些東西都是各個(gè)進(jìn)程共同要訪問的。

      分布式鎖的實(shí)現(xiàn)方式

      1、基于Redis的分布式鎖

      redis里面有一個(gè)方法叫做setnx ,如果設(shè)置成功則返回1,否則返回0,同時(shí)在設(shè)置的時(shí)候我們可以同時(shí)設(shè)置一個(gè)最大超時(shí)時(shí)間,這個(gè)是為了防止死鎖的發(fā)生,接下來執(zhí)行我們的業(yè)務(wù)邏輯,當(dāng)執(zhí)行完畢后執(zhí)行del這個(gè)命令,刪除這個(gè)鎖,從某種意義上說就是一個(gè)標(biāo)志位,在這種場合下稱之為鎖。代碼描述:

       Long result = jedis.setnx("lock","value")//步驟一,
       if(result!=null && result.intValue==1){
           jedis.expire("lock",50)  //步驟二,設(shè)置有效期,防止死鎖,
           .
           . 業(yè)務(wù)邏輯部分,在執(zhí)行業(yè)務(wù)邏輯期間,其他進(jìn)程通過setnx("lock","value"),返回0
           .   
           jedis.del("lock")//釋放這把鎖
        }else{
           System.out.pringln("獲取鎖失敗")
       }
      

      但是這時(shí)候表面上看似乎沒什么問題,但是如果在步驟一和步驟二之間出現(xiàn)了異常怎末辦也就是有效期沒有設(shè)置上而且也沒有刪除,此時(shí)lock這把鎖就一直存在Redis里面了,其他進(jìn)程想設(shè)置但始終會0因此又會導(dǎo)致死鎖出現(xiàn)的可能性

      2、基于Redis分布式鎖的升級版

      接著上面的問題來看,當(dāng)其它進(jìn)程想要獲取這這把鎖的時(shí)候那么這個(gè)進(jìn)程可以通過getset命令進(jìn)行重新設(shè)置的,但是我要知道到這個(gè)key的最大有效時(shí)間,我也不能每次都通過getset來覆蓋你啊,萬一其他線程正在使用呢?因此我們把方法一中的value進(jìn)行修改(當(dāng)前時(shí)間+最大有效期),通過時(shí)間進(jìn)行判斷。

      int lockTimeout = 50; //假設(shè)最大超時(shí)時(shí)間是50秒
       Long result = jedis.setnx("lock",String.valueOf(System.currentTimeMillis()+lockTimeout))//步驟一,
       if(result!=null && result.intValue==1){
           jedis.expire("lock",50)  //步驟二,設(shè)置有效期,防止死鎖,
           //業(yè)務(wù)邏輯部分.........在執(zhí)行業(yè)務(wù)邏輯期間,其他進(jìn)程通過setnx("lock","value"),返回0  
           jedis.del("lock")//釋放這把鎖
        }else{
            String lockValueStr  = RedisPoolUtil.get("lock");  //獲取其他線程設(shè)置的超時(shí)時(shí)間
           if(lockValueStr!=null && System.currentTimeMillis()>Long.parseLong(lockValueStr)){   //如果當(dāng)前時(shí)間大于其他線程設(shè)置的超時(shí)時(shí)間
              String ret = RedisPoolUtil.getSet("lock",String.valueOf(System.currentTimeMillis()+lockTimeout));
              if(ret==null||lockValueStr.equals(ret)){   //再次進(jìn)行判斷
                 jedis.expire("lock",50)   
                //執(zhí)行業(yè)務(wù)邏輯............
                  jedis.del("lock")//釋放這把鎖
               }else{
                  System.out.println("未能夠獲得分布式鎖");
                }
            }else{
                 System.out.println("未能夠獲取分布式鎖");
           } 
         }
      

      3、基于Redisson實(shí)現(xiàn)的分布式鎖

      Redisson為開發(fā)者提供了一系列具有分布式特性的常用工具類,接下來看看如何使用

      1、引入jar包

      <dependency>
                 <groupId>org.redisson</groupId>
                 <artifactId>redisson</artifactId>
                 <version>2.9.0</version>
             </dependency>
             <dependency>
                 <groupId>com.fasterxml.jackson.dataformat</groupId>
                 <artifactId>jackson-dataformat-avro</artifactId>
                 <version>2.9.0</version>
             </dependency>
      

      2、初始化配置

      public class RedissonManager {
          private Config config = new Config();
          private Redisson  redisson = null;
          public Redisson getRedisson() {
              return redisson;
          }
          private static String redisIp = "127。0.0.1";
          private static Integer redisPort = Integer.parseInt(PropertiesUtil.getProperty("redis1.port"));
          @PostConstruct
          private void init(){
              try {
                  config.useSingleServer().setAddress(new StringBuffer().append(redisIp).append(":").append(redisPort).toString());
                  redisson = (Redisson) Redisson.create(config);
                  log.info("init redisson finished");
              }catch (Exception e){
      
              }
          }
      }
      

      3、使用

      public void closeTask3(){
              RLock lock = redissonManager.getRedisson().getLock("lock");
              boolean getLock = false;
              try {
                  if(getLock=lock.tryLock(0,50, TimeUnit.SECONDS)){
                    //業(yè)務(wù)邏輯處理.....
                  }else{
                    System.out.print("獲取分布式鎖失敗")
                  }
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }finally {
                  if(!getLock){
                      return;
                  }
                  lock.unlock(); //解鎖
                  log.info("Redisson分布式鎖釋放鎖");
              }
          }
      

      使用Redison實(shí)現(xiàn)的分布式鎖,相對于我們自己來寫要非常簡單,當(dāng)然Redison的功能可不止這么多

      4、Zookeepr實(shí)現(xiàn)分布所鎖

      posted @ 2020-03-06 15:00  BingoJ  閱讀(780)  評論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 九九热精品在线观看| 天堂资源国产老熟女在线| 亚洲人成电影网站 久久影视| 国产精品综合色区av| 成人午夜免费无码视频在线观看| 国产毛片子一区二区三区| 国产精品一区高清在线观看| 午夜射精日本三级| 中文日产幕无线码一区中文| 亚洲人成电影网站色mp4| 久久亚洲精品成人av无| 92精品国产自产在线观看481页| 定南县| 无码AV中文字幕久久专区| 偷柏自拍亚洲综合在线| 99福利一区二区视频| 国产精品一区二区蜜臀av| 亚洲鸥美日韩精品久久| 国产一区二区不卡在线| 亚洲成aⅴ人在线电影| 国产久免费热视频在线观看| 国产精品中文字幕在线看| 日韩欧美视频一区二区三区| 国产成人精品永久免费视频| 亚洲大尺度一区二区三区| 国产日韩综合av在线| 北岛玲中文字幕人妻系列| 中国少妇人妻xxxxx| 国产成人精品2021欧美日韩| 亚洲精品一区二区毛豆| 国产精品久久久久久av| 国产精品福利自产拍久久| 天天做天天爱夜夜爽导航| 久爱www人成免费网站| 国产suv精品一区二区四| 人妻在线无码一区二区三区| 亚洲精品tv久久久久久久| 成人午夜免费无码视频在线观看| 国产精品无码一区二区在线 | 亚洲无av中文字幕在线| 欧美一区二区三区欧美日韩亚洲|