zookeeper java 锁_Java实现分布式锁-基于Zookeeper(3)

该博客介绍了如何利用Zookeeper创建一个分布式锁。首先,它创建业务根节点和瞬时有序节点,然后获取所有子节点并进行排序,判断创建的节点是否为第一个,从而决定是否获取到锁。当未获取到锁时,它会监听前一个节点,并在节点被删除时唤醒等待的线程。关闭时,会删除创建的节点并关闭Zookeeper连接。
摘要由CSDN通过智能技术生成

import lombok.extern.slf4j.Slf4j;

import org.apache.zookeeper.*;

import org.apache.zookeeper.data.Stat;

import java.io.IOException;

import java.util.Collections;

import java.util.List;

@Slf4j

public class ZkLock implements AutoCloseable, Watcher {

private ZooKeeper zooKeeper;

private String znode;

public ZkLock() throws IOException {

this.zooKeeper = new ZooKeeper("localhost:2181",

10000,this);

}

public boolean getLock(String businessCode) {

try {

//创建业务 根节点

Stat stat = zooKeeper.exists("/" + businessCode, false);

if (stat==null){

zooKeeper.create("/" + businessCode,businessCode.getBytes(),

ZooDefs.Ids.OPEN_ACL_UNSAFE,

CreateMode.PERSISTENT);

}

//创建瞬时有序节点 /order/order_00000001

znode = zooKeeper.create("/" + businessCode + "/" + businessCode + "_", businessCode.getBytes(),

ZooDefs.Ids.OPEN_ACL_UNSAFE,

CreateMode.EPHEMERAL_SEQUENTIAL);

//获取业务节点下 所有的子节点

List childrenNodes = zooKeeper.getChildren("/" + businessCode, false);

//子节点排序

Collections.sort(childrenNodes);

//获取序号最小的(第一个)子节点

String firstNode = childrenNodes.get(0);

//如果创建的节点是第一个子节点,则获得锁

if (znode.endsWith(firstNode)){

return true;

}

//不是第一个子节点,则监听前一个节点

String lastNode = firstNode;

for (String node:childrenNodes){

if (znode.endsWith(node)){

zooKeeper.exists("/"+businessCode+"/"+lastNode,true);

break;

}else {

lastNode = node;

}

}

synchronized (this){

wait();

}

return true;

} catch (Exception e) {

e.printStackTrace();

}

return false;

}

@Override

public void close() throws Exception {

zooKeeper.delete(znode,-1);

zooKeeper.close();

log.info("我已经释放了锁!");

}

@Override

public void process(WatchedEvent event) {

if (event.getType() == Event.EventType.NodeDeleted){

synchronized (this){

notify();

}

}

}

}

复制代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值