java zookeeper分布式锁demo
时间: 2023-10-06 13:14:08 浏览: 191
以下是一个基于 ZooKeeper 实现分布式锁的 Java Demo:
```java
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
public class DistributedLock implements Watcher {
private static final String ZK_ADDRESS = "localhost:2181";
private static final int SESSION_TIMEOUT = 5000;
private static final String LOCK_ROOT = "/locks";
private static final String LOCK_PREFIX = "lock_";
private String lockPath;
private ZooKeeper zk;
private CountDownLatch connectedSignal = new CountDownLatch(1);
private CountDownLatch lockSignal = new CountDownLatch(1);
public DistributedLock() throws Exception {
zk = new ZooKeeper(ZK_ADDRESS, SESSION_TIMEOUT, this);
connectedSignal.await();
Stat stat = zk.exists(LOCK_ROOT, false);
if (stat == null) {
zk.create(LOCK_ROOT, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
public boolean lock() throws Exception {
lockPath = zk.create(LOCK_ROOT + "/" + LOCK_PREFIX, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
while (true) {
String prevLock = getPrevLock();
if (prevLock == null) {
return true;
} else {
zk.exists(prevLock, true);
lockSignal.await();
}
}
}
public void unlock() throws Exception {
zk.delete(lockPath, -1);
}
private String getPrevLock() throws KeeperException, InterruptedException {
String prevLock = null;
String[] nodes = zk.getChildren(LOCK_ROOT, false).toArray(new String[0]);
for (int i = 0; i < nodes.length; i++) {
if (lockPath.endsWith(nodes[i])) {
if (i > 0) {
prevLock = LOCK_ROOT + "/" + nodes[i - 1];
}
break;
}
}
return prevLock;
}
@Override
public void process(WatchedEvent event) {
if (event.getState() == Event.KeeperState.SyncConnected) {
connectedSignal.countDown();
} else if (event.getType() == Event.EventType.NodeDeleted && event.getPath().equals(getPrevLock())) {
lockSignal.countDown();
}
}
}
```
这个 Demo 中,`DistributedLock` 类实现了分布式锁的基本操作。使用时,首先需要创建一个 `DistributedLock` 对象,然后调用 `lock` 方法获取锁,调用 `unlock` 方法释放锁。
这个 Demo 中使用 ZooKeeper 的 `EPHEMERAL_SEQUENTIAL` 模式创建了一个临时顺序节点,如果当前节点是序号最小的节点,则获取到锁。如果不是,则在当前节点的前一个节点上注册一个 Watcher,当前一个节点被删除时,当前节点就可以获取到锁了。
需要注意的是,这个 Demo 中的锁并没有考虑超时问题。在实际使用中,需要根据具体情况进行优化。
阅读全文