<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.7.0</version> </dependency>
@Slf4jpublic class ZkLock implements AutoCloseable, Watcher { private final ZooKeeper zk; private String znode; public ZkLock(String zkServers) throws Exception { zk = new ZooKeeper(zkServers, 600000, this); } public boolean getLock(String businessCode) { try { // 创建业务 根节点 Stat stat = zk.exists("/" + businessCode, false); if (stat == null) { zk.create("/" + businessCode, businessCode.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } // 创建瞬时有序节点 /order/order_000000001 znode = zk.create("/" + businessCode + "/" + businessCode + "_", businessCode.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); // 获取所有子节点 List<String> childrenNodes = zk.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)) { zk.exists("/" + businessCode + "/" + lastNode, true); break; } else { lastNode = node; } } synchronized (this) { wait(); } return true; } catch (KeeperException | InterruptedException e) { e.printStackTrace(); } return false; } @Override public void close() throws Exception { zk.delete(znode, -1); zk.close(); log.info("zk 释放了锁"); } @Override public void process(WatchedEvent watchedEvent) { if (watchedEvent.getType() == Event.EventType.NodeDeleted) { synchronized (this) { notify(); } } }}
@Slf4j@RestControllerpublic class ZkLockController { @RequestMapping("/zklock") public String zookeeperLock() { log.info("进入了方法"); try (ZkLock zkLock = new ZkLock("localhost:2181")){ if (zkLock.getLock("order")) { log.info("获取锁成功"); Thread.sleep(5000); } } catch (Exception e) { e.printStackTrace(); } log.info("结束了方法"); return "结束了方法"; }}