成人午夜一区二区_操碰在线视频_国产精品麻豆一区二区三区_中文黄色一级片_欧美日本中文字幕_高清视频91

當(dāng)前位置: 首頁 / 技術(shù)干貨 / 正文
分布式鎖的實(shí)現(xiàn)(二)

2023-01-12

   節(jié)點(diǎn)

  4.4. 子節(jié)點(diǎn)實(shí)現(xiàn)的鎖

  在生產(chǎn)環(huán)境中,使用子節(jié)點(diǎn)做分布式鎖的實(shí)現(xiàn)的場景是最常見的,包括阻塞型的鎖和非阻塞型的鎖。因此,設(shè)計(jì)子節(jié)點(diǎn)實(shí)現(xiàn)的鎖的父類,提供公共的處理邏輯。將阻塞型和非阻塞型的實(shí)現(xiàn)不同的邏輯分別在子類中實(shí)現(xiàn)即可。

  package com.qianfeng.lock.childNodeLock;

  import com.qianfeng.lock.ZkLocker;

  import com.qianfeng.lock.ZkLockerBase;

  import org.apache.zookeeper.CreateMode;

  import org.apache.zookeeper.KeeperException;

  import java.util.Collections;

  import java.util.List;

  /**

  * @author 千鋒大數(shù)據(jù)教研院 - 章魚哥

  * @company 北京千鋒互聯(lián)科技有限公司

  */

  public abstract class ZkChildNodeLockerBase extends ZkLockerBase implements ZkLocker {

  /**

  * 創(chuàng)建的子節(jié)點(diǎn)鎖的全路徑

  */

  protected String nodeFullPath;

  public ZkChildNodeLockerBase(String connectString, String lockName) {

  super(connectString, lockName);

  createLockNode();

  }

  public ZkChildNodeLockerBase(String lockName) {

  super();

  this.lockName = lockName;

  createLockNode();

  }

  // 創(chuàng)建鎖節(jié)點(diǎn)

  public void createLockNode() {

  // 1. 判斷節(jié)點(diǎn)是否存在

  if (!exists(getLockName())) {

  // 3. 創(chuàng)建鎖節(jié)點(diǎn)

  createNode(getLockName(), CreateMode.CONTAINER);

  }

  }

  @Override

  public boolean lock() {

  // 1. 在鎖節(jié)點(diǎn)下創(chuàng)建子節(jié)點(diǎn)

  this.nodeFullPath = createNode(getLockName() + "/child-", CreateMode.EPHEMERAL_SEQUENTIAL);

  // 2. 判斷是否可以成功上鎖

  return canLock();

  }

  @Override

  public boolean unlock() {

  return deleteNode(this.nodeFullPath);

  }

  @Override

  public boolean exists() {

  // 獲取當(dāng)前鎖節(jié)點(diǎn)下的子節(jié)點(diǎn)數(shù)量,如果大于0,說明有鎖存在

  try {

  Listchildren = getZkCli().getChildren(getLockName(), false);

  return children.size() > 0;

  } catch (KeeperException | InterruptedException ignored) {

  }

  return false;

  }

  protected abstract boolean canLock();

  /**

  * 獲取當(dāng)前創(chuàng)建的子節(jié)點(diǎn)之前的節(jié)點(diǎn)(根據(jù)序號)

  * @return 之前的節(jié)點(diǎn)

  */

  protected String getPreviousNode() {

  // 定義變量,記錄上一個節(jié)點(diǎn)名稱

  String previousNodeName = null;

  try {

  // 1. 獲取鎖節(jié)點(diǎn)下所有的子節(jié)點(diǎn)

  Listchildren = getZkCli().getChildren(getLockName(), false);

  // 2. 對所有的節(jié)點(diǎn)進(jìn)行名字排序

  Collections.sort(children);

  // 3. 獲取當(dāng)前創(chuàng)建的子節(jié)點(diǎn)名稱

  String childNodeName = this.nodeFullPath.substring(getLockName().length() + 1);

  // 4. 遍歷所有的節(jié)點(diǎn),進(jìn)行名稱的比對

  for (String child : children) {

  if (child.equals(childNodeName)) {

  break;

  }

  previousNodeName = child;

  }

  } catch (KeeperException | InterruptedException e) {

  e.printStackTrace();

  }

  return previousNodeName;

  }

  }

  4.5. 子節(jié)點(diǎn)實(shí)現(xiàn)的非阻塞型鎖

  package com.qianfeng.lock.childNodeLock;

  /**

  * @author 千鋒大數(shù)據(jù)教研院 - 章魚哥

  * @company 北京千鋒互聯(lián)科技有限公司

  */

  public class ZkChildNodeNoneBlockingLocker extends ZkChildNodeLockerBase {

  public ZkChildNodeNoneBlockingLocker(String connectString, String lockName) {

  super(connectString, lockName);

  }

  public ZkChildNodeNoneBlockingLocker(String lockName) {

  super(lockName);

  }

  @Override

  protected boolean canLock() {

  // 1. 判斷是否有之前的節(jié)點(diǎn)

  String previousNodeName = getPreviousNode();

  // 2. 如果不存在之前的節(jié)點(diǎn),說明上鎖成功

  if (previousNodeName == null) {

  return true;

  }

  // 3. 如果存在之前的節(jié)點(diǎn),說明上鎖失敗,刪除自己創(chuàng)建的子節(jié)點(diǎn)即可

  deleteNode(this.nodeFullPath);

  return false;

  }

  }

  4.6. 子節(jié)點(diǎn)實(shí)現(xiàn)的阻塞型鎖

  A程序在進(jìn)行上鎖的時候,發(fā)現(xiàn)已經(jīng)被其他的程序獲取到鎖了,自己需要等待其他的程序釋放鎖。基本的實(shí)現(xiàn)邏輯就是自己監(jiān)控已經(jīng)創(chuàng)建好的節(jié)點(diǎn),發(fā)現(xiàn)這個節(jié)點(diǎn)消失的時候,自己去創(chuàng)建節(jié)點(diǎn)。但是為什么沒有用節(jié)點(diǎn)作為鎖來實(shí)現(xiàn)阻塞型的鎖呢?是因?yàn)檫@里有“羊群效應(yīng)”。

  假如有100個程序來獲取鎖,結(jié)果發(fā)現(xiàn)鎖已經(jīng)被其他的程序注冊了,于是這100個程序都去監(jiān)聽這個節(jié)點(diǎn)。一旦這個節(jié)點(diǎn)被刪除,這100個程序都可以獲取到狀態(tài)的變更,會同時請求ZooKeeper創(chuàng)建節(jié)點(diǎn)。這樣會帶來瞬時的資源占用劇增,嚴(yán)重的甚至可能導(dǎo)致服務(wù)器宕機(jī)。因此,我們在實(shí)現(xiàn)阻塞型鎖的時候,使用的是有序的子節(jié)點(diǎn)來實(shí)現(xiàn)的,每一個程序監(jiān)控比自己編號小的節(jié)點(diǎn)即可。詳情可參考3.2.章節(jié)的內(nèi)容。

  package com.qianfeng.lock.childNodeLock;

  import org.apache.zookeeper.AddWatchMode;

  import org.apache.zookeeper.KeeperException;

  import java.util.concurrent.CountDownLatch;

  /**

  * @author 千鋒大數(shù)據(jù)教研院 - 章魚哥

  * @company 北京千鋒互聯(lián)科技有限公司

  */

  public class ZkChildNodeBlockingLocker extends ZkChildNodeLockerBase {

  // 等待釋放信號

  private CountDownLatch latch = new CountDownLatch(1);

  public ZkChildNodeBlockingLocker(String connectString, String lockName) {

  super(connectString, lockName);

  }

  public ZkChildNodeBlockingLocker(String lockName) {

  super(lockName);

  }

  @Override

  protected boolean canLock() {

  // 獲取自己創(chuàng)建的子節(jié)點(diǎn)之前序號的節(jié)點(diǎn)

  String previousNode = getPreviousNode();

  // 如果之前節(jié)點(diǎn)不存在,說明已經(jīng)上鎖成功

  if (previousNode == null) {

  return true;

  }

  // 如果有比當(dāng)前創(chuàng)建的節(jié)點(diǎn)序號更小的節(jié)點(diǎn),說明上鎖失敗,自己阻塞,監(jiān)聽之前的節(jié)點(diǎn)即可

  try {

  getZkCli().addWatch(getLockName() + "/" + previousNode, event -> {

  if (event.getType().equals(Event.EventType.NodeDeleted)) {

  // 說明之前節(jié)點(diǎn)被刪除掉了

  latch.countDown();

  }

  }, AddWatchMode.PERSISTENT);

  // 等待信號

  latch.await();

  } catch (KeeperException | InterruptedException e) {

  e.printStackTrace();

  }

  // 自己成為了最小的節(jié)點(diǎn),上鎖成功

  return true;

  }

  }

好程序員公眾號

  • · 剖析行業(yè)發(fā)展趨勢
  • · 匯聚企業(yè)項(xiàng)目源碼

好程序員開班動態(tài)

More+
  • HTML5大前端 <高端班>

    開班時間:2021-04-12(深圳)

    開班盛況

    開班時間:2021-05-17(北京)

    開班盛況
  • 大數(shù)據(jù)+人工智能 <高端班>

    開班時間:2021-03-22(杭州)

    開班盛況

    開班時間:2021-04-26(北京)

    開班盛況
  • JavaEE分布式開發(fā) <高端班>

    開班時間:2021-05-10(北京)

    開班盛況

    開班時間:2021-02-22(北京)

    開班盛況
  • Python人工智能+數(shù)據(jù)分析 <高端班>

    開班時間:2021-07-12(北京)

    預(yù)約報(bào)名

    開班時間:2020-09-21(上海)

    開班盛況
  • 云計(jì)算開發(fā) <高端班>

    開班時間:2021-07-12(北京)

    預(yù)約報(bào)名

    開班時間:2019-07-22(北京)

    開班盛況
IT培訓(xùn)IT培訓(xùn)
在線咨詢
IT培訓(xùn)IT培訓(xùn)
試聽
IT培訓(xùn)IT培訓(xùn)
入學(xué)教程
IT培訓(xùn)IT培訓(xùn)
立即報(bào)名
IT培訓(xùn)

Copyright 2011-2023 北京千鋒互聯(lián)科技有限公司 .All Right 京ICP備12003911號-5 京公網(wǎng)安備 11010802035720號

主站蜘蛛池模板: 亚洲精品久久久久久久久久久久久 | 五月婷综合 | 日韩国产精| 警花av一区二区三区 | 日韩精品中文字幕在线 | 国产成人精品免费视频 | 欧美精品一区二区视频 | 国产亚州av | 国产精品福利在线播放 | 希岛あいり中文字幕在线 | 精品中文字幕一区二区三区 | 午夜精品一区二区三区在线播放 | 国产精品美女久久久久aⅴ国产馆 | 黄色的视频在线观看 | 在线欧美日韩 | 亚洲不卡视频 | 久久亚洲一区二区三区四区 | 免费在线观看黄色网 | 国产激情一区二区三区在线观看 | 五月婷婷六月丁香 | 精品麻豆 | 国产日 | 国产激情 | 欧美一区二区三区在线视频 | 久久国产成人精品av | 91久久国产综合久久蜜月精品 | 久久久久久久久久久久91 | 日韩欧乱色一区二区三区在线 | 久久91精品国产91久久跳 | 88国产精品视频一区二区三区 | 在线三级av | 黄色免费在线播放 | 国产成人精品一区二区 | 日韩精品一区二区三区免费观看 | 国产精品国产a | 麻豆一区二区在线观看 | 成人免费视频网站在线看 | 99爱精品视频 | 久久精品青草 | 黄色网页在线看 | 国产精品日韩一区 |