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

2738

被折叠的 条评论
为什么被折叠?



