1、pom.xml引入如下依赖:2、代码实现: public class ZkLock implements AutoCloseable, Watcher { private static final Logger LOGGER = LoggerFactory.getLogger(ZkLock.class); 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 (Objects.isNull(stat)) { //创建业务根节点 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 org.apache.zookeeper zookeeper 3.4.14 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); } else { lastNode = node; } } synchronized (this) { wait(); } return true; } catch (Exception e) { e.printStackTrace(); } return false; } @Override public void close() throws Exception { //-1代表删除所有版本的数据 zooKeeper.delete(znode,-1); zooKeeper.close(); LOGGER.info("我已经释放了锁!"); } @Override public void process(WatchedEvent watchedEvent) { if (watchedEvent.getType() == Event.EventType.NodeDeleted) { synchronized (this) { notify(); } } } } 3、代码测试 public class ZkLockTest { private static final Logger LOGGER = LoggerFactory.getLogger(ZkLockTest.class); @Test public void testZkLock() { LOGGER.info("我进入了方法!"); try(ZkLock zkLock = new ZkLock()) { if (zkLock.getLock("order")) { Thread.sleep(10000); } } catch (Exception e) { e.printStackTrace(); } LOGGER.info("方法执行完成!"); } }



