<span id="35v3v"><th id="35v3v"></th></span>
<address id="35v3v"></address>

    <address id="35v3v"></address>
      <address id="35v3v"><listing id="35v3v"><meter id="35v3v"></meter></listing></address>
        <listing id="35v3v"><listing id="35v3v"></listing></listing>

        <listing id="35v3v"><listing id="35v3v"><menuitem id="35v3v"></menuitem></listing></listing>

        <noframes id="35v3v"><noframes id="35v3v">
        當前位置: 首頁 / 技術分享 / 正文
        分布式鎖的實現(一)

        2023-01-12

           節點

          4.1. 父類的設計

          設計父類,提供連接ZooKeeper服務端的邏輯、節點操作的邏輯,所有方式實現的鎖都需要繼承自這個類。

          package com.qianfeng.lock;

          import org.apache.zookeeper.*;

          import org.apache.zookeeper.data.Stat;

          import java.io.IOException;

          import java.util.concurrent.CountDownLatch;

          /**

          * @author 千鋒大數據教研院 - 章魚哥

          * @company 北京千鋒互聯科技有限公司

          */

          public abstract class ZkLockerBase implements Watcher {

          /**

          * 操作的鎖名稱

          */

          protected String lockName;

          /**

          * ZooKeeper連接客戶端

          */

          private ZooKeeper zkCli = null;

          /**

          * 確??梢赃B接到ZooKeeper客戶端

          */

          private final CountDownLatch latch = new CountDownLatch(1);

          /**

          * 鎖的根節點名稱

          */

          protected String rootNodeName = "/zk-lock";

          /**

          * 連接到預設的服務器

          */

          public ZkLockerBase() {

          this("qianfeng01:2181,qianfeng02:2181,qianfeng03:2181");

          }

          /**

          * 連接到ZooKeeper的指定服務端

          * @param connectString 連接字符串

          */

          public ZkLockerBase(String connectString) {

          try {

          // 連接到ZooKeeper服務端

          this.zkCli = new ZooKeeper(connectString, 5000, this);

          // 等待連接成功的信號

          this.latch.await();

          // 創建根節點

          createRootNode();

          } catch (IOException | InterruptedException e) {

          e.printStackTrace();

          }

          }

          public ZkLockerBase(String connectString, String lockName) {

          this(connectString);

          this.lockName = lockName;

          }

          /**

          * 創建節點

          * @param nodeName 創建的節點名稱

          * @param createMode 創建模式

          * @return 創建成功的節點名稱,如果創建失敗,返回null

          */

          public String createNode(String nodeName, CreateMode createMode) {

          try {

          // 創建節點,并返回創建成功之后的節點名稱

          return this.zkCli.create(nodeName, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode);

          } catch (KeeperException | InterruptedException ignored) {

          }

          return null;

          }

          /**

          * 刪除節點

          * @param nodeName 刪除的節點名稱

          * @return 刪除的結果

          */

          public boolean deleteNode(String nodeName) {

          try {

          // 刪除節點

          this.zkCli.delete(nodeName, -1);

          return true;

          } catch (InterruptedException | KeeperException ignored) {

          }

          return false;

          }

          /**

          * 判斷節點是否存在

          * @param nodeName 節點的名字

          * @return 是否存在

          */

          public boolean exists(String nodeName) {

          try {

          Stat exists = zkCli.exists(nodeName, false);

          return exists != null;

          } catch (KeeperException | InterruptedException e) {

          e.printStackTrace();

          }

          return false;

          }

          /**

          * 創建根節點,存放所有的節點或者子節點實現的鎖

          */

          public void createRootNode() {

          if (!exists(this.rootNodeName)) {

          createNode(this.rootNodeName, CreateMode.CONTAINER);

          }

          }

          public String getLockName() {

          return this.rootNodeName + "/" + lockName;

          }

          public ZooKeeper getZkCli() {

          return zkCli;

          }

          @Override

          public void process(WatchedEvent event) {

          switch (event.getType()) {

          case None:

          if (event.getState().equals(Event.KeeperState.SyncConnected)) {

          // 說明連接到服務端成功

          this.latch.countDown();

          }

          case NodeCreated:

          processCreatedNode(event);

          break;

          case NodeDeleted:

          processDeleteNode(event);

          break;

          case NodeChildrenChanged:

          processChildernChange(event);

          break;

          }

          }

          // 創建節點回調

          protected void processCreatedNode(WatchedEvent event) {}

          // 刪除節點回調

          protected void processDeleteNode(WatchedEvent event) {}

          // 子節點變更回調

          protected void processChildernChange(WatchedEvent event) {}

          }

          鎖接口的設計

          提供所有的鎖必須要實現的功能,制定鎖的規范。

          package com.qianfeng.lock;

          /**

          * ZooKeeper分布式鎖通用接口

          *

          * @author 千鋒大數據教研院 - 章魚哥

          * @company 北京千鋒互聯科技有限公司

          */

          public interface ZkLocker {

          /**

          * 上鎖

          */

          boolean lock();

          /**

          * 解鎖

          */

          boolean unlock();

          /**

          * 判斷鎖是否存在

          * @return 是否存在

          */

          boolean exists();

          }

          4.3. 節點實現的非阻塞性鎖

          package com.qianfeng.lock.nodeLock;

          import com.qianfeng.lock.ZkLocker;

          import com.qianfeng.lock.ZkLockerBase;

          import org.apache.zookeeper.CreateMode;

          /**

          * @author 千鋒大數據教研院 - 章魚哥

          * @company 北京千鋒互聯科技有限公司

          */

          public class ZkLockerNodeNoneBlockingLocker extends ZkLockerBase implements ZkLocker {

          public ZkLockerNodeNoneBlockingLocker(String connectString, String lockName) {

          super(connectString, lockName);

          }

          public ZkLockerNodeNoneBlockingLocker(String lockName) {

          super();

          this.lockName = lockName;

          }

          /**

          * 上鎖

          */

          @Override

          public boolean lock() {

          // 1. 拼接完整的節點路徑

          String lockNode = this.rootNodeName + "/" + lockName;

          // 2. 創建鎖

          return createNode(lockNode, CreateMode.EPHEMERAL) != null;

          }

          /**

          * 解鎖

          */

          @Override

          public boolean unlock() {

          // 1. 拼接完整的節點路徑

          String lockNode = this.rootNodeName + "/" + lockName;

          // 2. 刪除鎖

          return deleteNode(lockNode);

          }

          /**

          * 判斷鎖是否存在

          *

          * @return 是否存在

          */

          @Override

          public boolean exists() {

          // 1. 拼接完整的節點路徑

          String lockNode = this.rootNodeName + "/" + lockName;

          // 2. 判斷是否存在

          return super.exists(lockNode);

          }

          }

        好程序員公眾號

        • · 剖析行業發展趨勢
        • · 匯聚企業項目源碼

        好程序員開班動態

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

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

          開班盛況

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

          開班盛況
        • 大數據+人工智能 <高端班>

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

          開班盛況

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

          開班盛況
        • JavaEE分布式開發 <高端班>

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

          開班盛況

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

          開班盛況
        • Python人工智能+數據分析 <高端班>

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

          預約報名

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

          開班盛況
        • 云計算開發 <高端班>

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

          預約報名

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

          開班盛況
        在線咨詢
        試聽
        入學教程
        立即報名

        Copyright 2011-2023 北京千鋒互聯科技有限公司 .All Right 京ICP備12003911號-5 京公網安備 11010802035720號

        黑人100部Av解禁片
        <span id="35v3v"><th id="35v3v"></th></span>
        <address id="35v3v"></address>

          <address id="35v3v"></address>
            <address id="35v3v"><listing id="35v3v"><meter id="35v3v"></meter></listing></address>
              <listing id="35v3v"><listing id="35v3v"></listing></listing>

              <listing id="35v3v"><listing id="35v3v"><menuitem id="35v3v"></menuitem></listing></listing>

              <noframes id="35v3v"><noframes id="35v3v">