zookeeper利用模板设计模式实现分布式锁

1.实现pom文件的导入
在这里插入图片描述
2.设置好日志输出的配置
在这里插入图片描述
以上为基础配置,当然你的虚拟机要有配置的docker容器zookeeper。
主要思想:
a、在获取分布式锁的时候在locker节点下创建节点,释放锁的时候释放该节点。

b、客户端调用createNode方法在path下创建临时顺序节点,然后获取该子节点,注意此时不用设置任何Watcher。

c、客户端获取到所有的节点path之后,那么就认为该客户端获取到了锁。

d、如果发现自己创建的节点已经占用,说明自己还没有获取到锁,此时客户然后对其调用exist()方法,同时对其注册事件监听器,客户端等待。

e、之后,让这个被关注的节点删除,则客户端的Watcher会收到相应通知,如果不是则重复以上步骤继续获取到比自己小的一个节点并注册监听。

当然我们要用到模板设计模式,在阎宏博士的《JAVA与模式》一书中开头是这样描述模板方法(Template Method)模式的:

模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。
  首先定义加锁和释放锁的接口中方法

public interface Zklock {

    public void zkLock();
   public void zkUnLock();

}

然后做一个抽象模板类,里面配置好zookeeper信息和路径,子类也可以使用

public abstract class ZookperAbstractLock implements Zklock {
    public static final String ZKSERVER="192.168.111.111:2181";
    public static final int  TimeOut=45*1000;
    protected String path="/zklock0401";

  //这是countdown锁,实现类将会体现他的价值
    protected CountDownLatch countDownLatch=null;
    ZkClient zkClient=new ZkClient(ZKSERVER,TimeOut);
    @Override
    public void zkLock() {
     if(tryZklock()){
         System.out.println(Thread.currentThread().getName()+"占用锁成功");
     }else{
         waitZkLock();
         zkLock();
     }
    }

    protected abstract void waitZkLock();

    public abstract boolean tryZklock();

    @Override
    public void zkUnLock() {
        if(zkClient !=null){
           zkClient.close();
        }
        System.out.println(Thread.currentThread().getName()+"\t释放锁成功");
        System.out.println();
        System.out.println();
    }
}

下面就是具体代码正在实现
1首先是实现上锁的方法,这个容易实现,在该路径下建立节点就可以
    public boolean tryZklock() {

        try {
            zkClient.createEphemeral(path);
            return true;
        } catch (RuntimeException e) {
            e.printStackTrace();
            return false;
        }
    }
    
    2.其他服务进来就要等待实现
     a:要实现对该节点的监听,我们监听的是删除事件
     b:当存在该路径,调用exists方法,我们就要等待,不能往下走,于是就用到了     contdownlunch
     c:当监听到删除事件时,countDownLatch.countDown()。抢到监听器之后用完就释放
     
 public void waitZkLock() {
        IZkDataListener iZkDataListener=new IZkDataListener() {
            @Override
            public void handleDataChange(String s, Object o) throws Exception {

            }

            @Override
            public void handleDataDeleted(String s) throws Exception {
                 if(countDownLatch!=null){
                      countDownLatch.countDown();
                 }
            }
        };

        zkClient.subscribeDataChanges(path,iZkDataListener);
      if(zkClient.exists(path)) {
          //等着不能往下走
          countDownLatch = new CountDownLatch(1);

          try {
              countDownLatch.await();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
      //抢到监听器之后用完就释放
      zkClient.unsubscribeDataChanges(path,iZkDataListener);

    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值