Zookeeper分布式锁实现

本文介绍了一种基于ZooKeeper实现的分布式锁机制。通过创建临时节点并使用CountDownLatch进行等待,确保了并发场景下资源操作的一致性和隔离性。当尝试获取锁失败时,代码将进入自旋状态,直至成功获取锁。

实现思路:

 

 

实现代码:

package com.hangzhou.executor.zkLock;

public interface ZkLock {
    /**
     * zookeeper创建临时节点
     */
     void ZkLock();

    /**
     * 删除临时节点
     */
    void ZkUnLock();


}
package com.hangzhou.executor.zkLock;

import org.I0Itec.zkclient.ZkClient;

import java.util.concurrent.CountDownLatch;

/**
 * Template基类 
 */
public abstract class ZkAbstractLock implements ZkLock {

    /**
     * zookeeper连接超时时间
     */
    private static final int TIME_OUT = 50 * 1000;

    /**
     * zookeeper的服务器连接IP地址
     */
    private static final String ZK_SERVERS = "zookeeper的服务器连接IP地址";

    /**
     * zookeeper客户端远程连接
     */
    protected ZkClient zkClient = new ZkClient(ZK_SERVERS, TIME_OUT);

    /**
     * zookeeper的分布式锁所创建的目录
     */
    protected static final String PATH = "/zkLock";

    protected CountDownLatch countDownLatch = null;

    @Override
    public void ZkLock() {
        if (tryZkLock()) {
            zkClient.createEphemeral(PATH);
        } else {
            waitZkLock();
            //自旋调用尝试获取zookeeper分布式锁
            ZkLock();
        }
    }

    protected abstract void waitZkLock();

    protected abstract boolean tryZkLock();

    @Override
    public void ZkUnLock() {
        if (zkClient != null) {
            // 释放锁 关闭当前会话,zookeeper的临时节点会自动删除
            zkClient.close();
        }

    }
}

 

 

package com.hangzhou.executor.zkLock;

import org.I0Itec.zkclient.IZkDataListener;

import java.util.concurrent.CountDownLatch;

/**
 * 子类实现 抽象方法
 */
public class ZkDistributeLock extends ZkAbstractLock {
    @Override
    protected void waitZkLock() {
        IZkDataListener zkDataListener = new IZkDataListener() {
            @Override
            public void handleDataChange(String s, Object o) throws Exception {

            }

            //监听是否删除临时节点,如果删除临时节点,则等待线程-1
            @Override
            public void handleDataDeleted(String s) throws Exception {
                if (countDownLatch != null) {
                    countDownLatch.countDown();
                }
            }
        };
        //注册监听器
        zkClient.subscribeDataChanges(PATH, zkDataListener);
        if (zkClient.exists(PATH)) {

            countDownLatch = new CountDownLatch(1);
            try {
                //只能等着不能往下走,只能等待临时节点被删除
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //释放监听器
        zkClient.unsubscribeDataChanges(PATH, zkDataListener);
    }

    @Override
    protected boolean tryZkLock() {
        try {
            //zookeeper的临时节点不能重复创建,如若创建失败,则会抛出异常
            zkClient.createEphemeral(PATH);
            return true;
        } catch (RuntimeException e) {
            e.printStackTrace();
            return false;
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值