1. <dependency>
    2. <groupId>org.apache.zookeeper</groupId>
    3. <artifactId>zookeeper</artifactId>
    4. <version>3.7.0</version>
    5. </dependency>
    1. @Slf4j
    2. public class ZkLock implements AutoCloseable, Watcher {
    3. private final ZooKeeper zk;
    4. private String znode;
    5. public ZkLock(String zkServers) throws Exception {
    6. zk = new ZooKeeper(zkServers, 600000, this);
    7. }
    8. public boolean getLock(String businessCode) {
    9. try {
    10. // 创建业务 根节点
    11. Stat stat = zk.exists("/" + businessCode, false);
    12. if (stat == null) {
    13. zk.create("/" + businessCode, businessCode.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    14. }
    15. // 创建瞬时有序节点 /order/order_000000001
    16. znode = zk.create("/" + businessCode + "/" + businessCode + "_", businessCode.getBytes(),
    17. ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
    18. // 获取所有子节点
    19. List<String> childrenNodes = zk.getChildren("/" + businessCode, false);
    20. // 子节点排序
    21. Collections.sort(childrenNodes);
    22. // 获取序号最小的(第一个)节点
    23. String firstNode = childrenNodes.get(0);
    24. // 判断是否是第一个节点
    25. if (znode.endsWith(firstNode)) {
    26. return true;
    27. }
    28. // 获取第一个节点的前一个节点
    29. String lastNode = firstNode;
    30. for (String node : childrenNodes) {
    31. if (znode.endsWith(node)) {
    32. zk.exists("/" + businessCode + "/" + lastNode, true);
    33. break;
    34. } else {
    35. lastNode = node;
    36. }
    37. }
    38. synchronized (this) {
    39. wait();
    40. }
    41. return true;
    42. } catch (KeeperException | InterruptedException e) {
    43. e.printStackTrace();
    44. }
    45. return false;
    46. }
    47. @Override
    48. public void close() throws Exception {
    49. zk.delete(znode, -1);
    50. zk.close();
    51. log.info("zk 释放了锁");
    52. }
    53. @Override
    54. public void process(WatchedEvent watchedEvent) {
    55. if (watchedEvent.getType() == Event.EventType.NodeDeleted) {
    56. synchronized (this) {
    57. notify();
    58. }
    59. }
    60. }
    61. }
    1. @Slf4j
    2. @RestController
    3. public class ZkLockController {
    4. @RequestMapping("/zklock")
    5. public String zookeeperLock() {
    6. log.info("进入了方法");
    7. try (ZkLock zkLock = new ZkLock("localhost:2181")){
    8. if (zkLock.getLock("order")) {
    9. log.info("获取锁成功");
    10. Thread.sleep(5000);
    11. }
    12. } catch (Exception e) {
    13. e.printStackTrace();
    14. }
    15. log.info("结束了方法");
    16. return "结束了方法";
    17. }
    18. }