Zookeeper 分布式锁实现原理:
- 在zk创建临时节点,只要谁能创建节点成功,就能获取锁。
- 如果没能创建成功就等待
- 使用事件监听器监听节点是否删除,从而结束等待
1、引入 zkClient 依赖
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
2、分布式锁代码
public class Lock {
private final String PATH = "/lock";
ZkClient zkClient = new ZkClient("127.0.0.1:2181");
private CountDownLatch countDownLatch = null;
public void getLock() {
if (tryLog()) {
System.out.println("##获取lock锁的资源####");
} else {
waitLock();
getLock();
}
}
public boolean isExit() {
return this.zkClient.exists(this.PATH);
}
public boolean tryLog() {
try {
this.zkClient.createEphemeral(this.PATH);
return true;
} catch (Exception e) {
return false;
}
}
public void unLock() {
if (zkClient != null) {
zkClient.close();
System.out.println("释放锁资源.");
}
}
public void waitLock() {
IZkDataListener zkDataListener = new IZkDataListener() {
// 节点被删除
@Override
public void handleDataChange(String dataPath, Object data) throws Exception {
if (countDownLatch != null) {
countDownLatch.countDown();
}
}
// 节点发生改变
@Override
public void handleDataDeleted(String dataPath) throws Exception {
}
};
// 注册事件
zkClient.subscribeDataChanges(this.PATH, zkDataListener);
if (isExit()) {
// 创建信号量
countDownLatch = new CountDownLatch(1);
try {
countDownLatch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
// 删除监听
zkClient.unsubscribeDataChanges(this.PATH, zkDataListener);
}
}
3、在线程中 调用Lock对象