分布式共享锁

11.1 需求描述

在我们自己的分布式业务系统中,可能会存在某种资源,需要被整个系统的各台服务器共享访问,但是只允许一台服务器同时访问

 

11.2 设计思路

 

11.3 代码开发

 

public class DistributedClientMy {

     // 超时时间

     private static final int SESSION_TIMEOUT = 5000;

     // zookeeper server列表

     private String hosts = "spark01:2181,spark02:2181,spark03:2181";

     private String groupNode = "locks";

     private String subNode = "sub";

     private boolean haveLock = false;

 

     private ZooKeeper zk;

     // 当前client创建的子节点

     private volatile String thisPath;

 

     /**

      * 连接zookeeper

      */

     public void connectZookeeper() throws Exception {

          zk = new ZooKeeper("spark01:2181", SESSION_TIMEOUT, new Watcher() {

               public void process(WatchedEvent event) {

                    try {

 

                         // 子节点发生变化

                         if (event.getType() == EventType.NodeChildrenChanged && event.getPath().equals("/" + groupNode)) {

                              // thisPath是否是列表中的最小节点

                              List<String> childrenNodes = zk.getChildren("/" + groupNode, true);

                              String thisNode = thisPath.substring(("/" + groupNode + "/").length());

                              // 排序

                              Collections.sort(childrenNodes);

                              if (childrenNodes.indexOf(thisNode) == 0) {

                                   doSomething();

                                   thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE,

                                             CreateMode.EPHEMERAL_SEQUENTIAL);

                              }

                         }

                    } catch (Exception e) {

                         e.printStackTrace();

                    }

               }

          });

 

          // 创建子节点

          thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE,

                    CreateMode.EPHEMERAL_SEQUENTIAL);

 

          // wait一小会, 让结果更清晰一些

          Thread.sleep(new Random().nextInt(1000));

 

          // 监听子节点的变化

          List<String> childrenNodes = zk.getChildren("/" + groupNode, true);

 

          // 列表中只有一个子节点, 那肯定就是thisPath, 说明client获得锁

          if (childrenNodes.size() == 1) {

               doSomething();

               thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE,

                         CreateMode.EPHEMERAL_SEQUENTIAL);

          }

     }

 

     /**

      * 共享资源的访问逻辑写在这个方法中

      */

     private void doSomething() throws Exception {

          try {

               System.out.println("gain lock: " + thisPath);

               Thread.sleep(2000);

               // do something

          } finally {

               System.out.println("finished: " + thisPath);

               // 将thisPath删除, 监听thisPath的client将获得通知

               // 相当于释放锁

               zk.delete(this.thisPath, -1);

          }

     }

 

     public static void main(String[] args) throws Exception {

          DistributedClientMy dl = new DistributedClientMy();

          dl.connectZookeeper();

          Thread.sleep(Long.MAX_VALUE);

     }

 

    

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值