基于Zookeeper使用curator实现分布式锁和节点数据监听

1、添加相关依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.cxb</groupId>
    <artifactId>springboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-hello</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!-- 链接池 -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- log start -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>5.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>5.2.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
# zk配置
curator:
  retryCount: 5      #重试次数
  baseSleepTimeMs: 1000   #重试间隔时间
  connectString: 127.0.0.1:2181    # zk地址
  sessionTimeoutMs: 60000          #session超时时间
  connectionTimeoutMs: 5000         #连接超时时间

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    data-username: root
    data-password: 123456
    url: jdbc:mysql:///activiti?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT

server:
  port: 8081

zookeeper:
  server: 127.0.0.1:2181
  sleep-time: 1000
  max-retries: 3
  session-timeout: 1500
  connection-timerout: 5000

2、编码实现

package com.cxb.springboot.common;

import java.util.concurrent.TimeUnit;

/**
 * @Classname AbstractLock
 * @Description TODO
 * @Date 2023/3/28 22:41
 * @Created by Administrator
 */
public abstract class AbstractLock<T> {

    /**
     * 锁路径
     */
    protected String lockPath;

    /**
     * 超时时间
     */
    protected long time;

    protected TimeUnit timeUnit;

    public AbstractLock(String lockPath, long time, TimeUnit timeUnit) {
        this.lockPath = lockPath;
        this.time = time;
        this.timeUnit = timeUnit;
    }

    public void setLockPath(String lockPath) {
        this.lockPath = lockPath;
    }

    public String getLockPath() {
        return lockPath;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public void setTimeUnit(TimeUnit timeUnit) {
        this.timeUnit = timeUnit;
    }

    public TimeUnit getTimeUnit() {
        return timeUnit;
    }

    /**
     * 执行业务的方法
     *
     * @return
     */
    public abstract T execute();
}
package com.cxb.springboot.common;

/**
 * @Classname ZookeeperClient
 * @Description TODO
 * @Date 2023/3/28 22:38
 * @Created by Administrator
 */
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;

@Slf4j
public class ZookeeperClient {

    private CuratorFramework curatorFramework;

    public ZookeeperClient(CuratorFramework curatorFramework) {
        this.curatorFramework = curatorFramework;
    }

    public <T> T lock(AbstractLock<T> abstractLock) {
        //获取锁路径
        String lockPath = abstractLock.getLockPath();
        //创建InterProcessMutex实例
        InterProcessMutex lock = new InterProcessMutex(curatorFramework, lockPath); //创建锁对象
        boolean success = false;
        try {
            try {
                //加锁
                success = lock.acquire(abstractLock.getTime(), abstractLock.getTimeUnit()); //获取锁
            } catch (Exception e) {
                throw new RuntimeException("尝试获取锁异常:" + e.getMessage() + ", lockPath " + lockPath);
            }
            //判断是否加锁成功
            if (success) {
                return abstractLock.execute();
            } else {
                log.info("获取锁失败,返回null");
                return null;
            }
        } finally {
            try {
                if (success) {
                    //释放锁
                    lock.release();
                }
            } catch (Exception e) {
                log.error("释放锁异常: {}, lockPath {}", e.getMessage(), lockPath);
            }
        }
    }

    //bean的销毁方法
    public void destroy() {
        try {
            log.info("ZookeeperClient销毁方法,如果zookeeper连接不为空,则关闭连接");
            if (getCuratorFramework() != null) {
                //这种方式比较优雅的关闭连接
                getCuratorFramework().close();
            }
        } catch (Exception e) {
            log.error("stop zookeeper client error {}", e.getMessage());
        }
    }

    public CuratorFramework getCuratorFramework() {
        return curatorFramework;
    }
}
package com.cxb.springboot.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @Classname WrapperZk
 * @Description TODO
 * @Date 2023/3/28 21:57
 * @Created by Administrator
 */
@Data
@Component
@ConfigurationProperties(prefix = "curator")
public class WrapperZk {

    private int retryCount;

    private int elapsedTimeMs;

    private String connectString;

    private int sessionTimeoutMs;

    private int connectionTimeoutMs;

    private int baseSleepTimeMs;
}
package com.cxb.springboot.config;

import com.cxb.springboot.common.ZookeeperClient;
import com.cxb.springboot.listener.ZookeeperWatcherListener;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.CuratorCache;
import org.apache.curator.framework.recipes.cache.CuratorCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

import static com.cxb.springboot.service.CuratorLockService.dataPath;

/**
 * @Classname ZkConfiguration
 * @Description TODO
 * @Date 2023/3/28 21:57
 * @Created by Administrator
 */
@Configuration
@Slf4j
public class ZkConfiguration {

    @Resource
    private WrapperZk wrapperZk;

    /**
     * 其中RetryPolicy为重试策略,第一个参数为baseSleepTimeMs初始的sleep时间,
     * 用于计算之后的每次重试的sleep时间。第二个参数为maxRetries,最大重试次数。
     * @return
     */
    /*@Bean(initMethod = "start")
    public CuratorFramework curatorFramework() {
        RetryPolicy retrYPolicy = new ExponentialBackoffRetry(wrapperZk.getBaseSleepTimeMs(),
                wrapperZk.getRetryCount());
        CuratorFramework client = CuratorFrameworkFactory
                .newClient(wrapperZk.getConnectString(), retrYPolicy);
        log.info("zk curator初始化完成...");
        return client;
    }*/

    @Resource
    private ZookeeperProperties zookeeperProperties;

    @Bean
    public CuratorFramework curatorFrameworkClient() {
        //重试策略,ExponentialBackoffRetry(1000,3)这里表示等待1s重试,最大重试次数为3次
        RetryPolicy policy = new ExponentialBackoffRetry(zookeeperProperties.getSleepTime(),
                zookeeperProperties.getMaxRetries());
        //构建CuratorFramework实例
        CuratorFramework curatorFrameworkClient = CuratorFrameworkFactory
                .builder()
                .connectString(zookeeperProperties.getServer())
                .sessionTimeoutMs(zookeeperProperties.getSessionTimeout())
                .connectionTimeoutMs(zookeeperProperties.getConnectionTimeout())
                .retryPolicy(policy)
                .build();
        // 启动实例
        curatorFrameworkClient.start();
        CuratorCache curatorCache = CuratorCache.
                build(curatorFrameworkClient, dataPath, CuratorCache.Options.SINGLE_NODE_CACHE);
        CuratorCacheListener listener = CuratorCacheListener
                .builder()
                .forAll(new ZookeeperWatcherListener())
                .build();
        curatorCache.listenable().addListener(listener);
        curatorCache.start();

        return curatorFrameworkClient;
    }

    /**
     * 采用这种方式注册bean可以比较优雅的关闭连接
     */
    @Bean(destroyMethod = "destroy")
    public ZookeeperClient zookeeperClient(CuratorFramework curatorFrameworkClient) {
        return new ZookeeperClient(curatorFrameworkClient);
    }

}

package com.cxb.springboot.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @Classname ZookeeperProperties
 * @Description TODO
 * @Date 2023/3/28 22:34
 * @Created by Administrator
 */
@Data
@Component
@ConfigurationProperties(prefix = "zookeeper")
public class ZookeeperProperties {

    /**
     * zookeeper服务地址
     */
    private String server;

    /**
     * 重试等待时间
     */
    private int sleepTime;

    /**
     * 最大重试次数
     */
    private int maxRetries;

    /**
     * session超时时间
     */
    private int sessionTimeout;

    /**
     * 连接超时时间
     */
    private int connectionTimeout;

}
package com.cxb.springboot.controller;

import com.cxb.springboot.service.CuratorLockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Classname CuratorController
 * @Description TODO
 * @Date 2023/3/28 22:43
 * @Created by Administrator
 */
@RequestMapping("/curator")
@RestController
public class CuratorController {

    @Autowired
    private CuratorLockService curatorLockService;

    /**
     * localhost:8081/curator/deduct?lockId=1001
     * @param lockId
     * @return
     */
    @RequestMapping("/deduct")
    public String deduct(String lockId) {
        return curatorLockService.inventoryDeduct(lockId);
    }

}

package com.cxb.springboot.controller;

import com.cxb.springboot.config.ZkConfiguration;
import com.cxb.springboot.service.CuratorLockService;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @Classname MicroController
 * @Description TODO
 * @Date 2023/3/28 22:03
 * @Created by Administrator
 */
@Controller
@RequestMapping("/zk")
@Slf4j
public class MicroController {

    private final static String PATH = "/rootLock";

    private final static String ID_PATH = "/root/rootId";

    @Autowired
    ZkConfiguration zkConfiguration;

    @Autowired
    private CuratorLockService curatorLockService;

    /**
     * 这里我用的是最常用的可重入排他锁,也是公平锁(InterProcessMutex)
     * InterProcessMutex:分布式可重入排它锁
     * InterProcessSemaphoreMutex:分布式排它锁
     * InterProcessReadWriteLock:分布式读写锁
     * InterProcessMultiLock:将多个锁作为单个实体管理的容器
     * @return
     * @throws Exception
     */
    @GetMapping("/lock")
    @ResponseBody
    public String getLock1() throws Exception {
        InterProcessMutex lock = new InterProcessMutex(zkConfiguration.curatorFrameworkClient(), PATH);
        for (int i = 0; i < 30; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        log.info(Thread.currentThread().getName() + "尝试获取锁....");
                        lock.acquire();
                        log.info(Thread.currentThread().getName() + "获取锁成功....");
                        log.info(Thread.currentThread().getName() + "开始执行业务逻辑....");
                        Thread.sleep(10000);
                        lock.release();
                        log.info(Thread.currentThread().getName() + "释放锁成功....");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            thread.start();
        }
        return "execute success";
    }

    @GetMapping("/id")
    @ResponseBody
    public String createId(String data) throws Exception {
        return curatorLockService.getDistributedId(ID_PATH, data);
    }

}

节点数据变化监听器 

package com.cxb.springboot.listener;

import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.CuratorCacheListener;

/**
 * @Classname ZookeeperWatcherListener
 * @Description TODO
 * @Date 2023/3/28 23:11
 * @Created by Administrator
 */
public class ZookeeperWatcherListener implements CuratorCacheListener {

    @Override
    public void event(Type type, ChildData oldData, ChildData data) {
        System.out.println("事件类型: " + type + " :oldData: " + new String(oldData.getData()) + " :data: " + new String(data.getData()));
    }
}
package com.cxb.springboot.service;

/**
 * @Classname CuratorLockService
 * @Description TODO
 * @Date 2023/3/28 22:41
 * @Created by Administrator
 */

import com.cxb.springboot.common.AbstractLock;
import com.cxb.springboot.common.ZookeeperClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class CuratorLockService {

    @Autowired
    private ZookeeperClient zookeeperClient;

    @Autowired
    private CuratorFramework curatorFramework;

    //库存存取的路径
    public static final String dataPath = "/root/data/stock";

    //初始化库存的路径
    public static final String initPath = "/root/init/stock";

    /**
     * 此方法系统启动执行,使用zookeeper存一个库存用于测试,这里也使用了锁。(只是一个模拟初始化库存的方法)
     */
    @PostConstruct
    public void init() {
        zookeeperClient.lock(new AbstractLock<Boolean>(initPath, 20, TimeUnit.SECONDS) {
            @Override
            public Boolean execute() {
                try {
                    //判断是否存在路径
                    Stat stat = curatorFramework.checkExists().forPath(dataPath);
                    if (stat == null) {
                        //为空则不存在,则创建并设置库存值
                        curatorFramework.create().creatingParentContainersIfNeeded().forPath(dataPath, "1000".getBytes());
                        log.info("初始化数据完成");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
                return true;
            }
        });
    }

    public String inventoryDeduct(String lockId) {
        //我这里是演示,实际对于不同的业务锁路径设置不同,比如支付和订单设置为"/root/pay/"和"/root/order/"
        String lockPath = "/root/frank/" + lockId;
        //调用加锁方法
        Integer result = zookeeperClient.lock(new AbstractLock<Integer>(lockPath, 10, TimeUnit.SECONDS) {
            @Override
            public Integer execute() {
                try {
                    //模拟业务处理
                    byte[] bytes = curatorFramework.getData().forPath(dataPath);
                    String data = new String(bytes);
                    int stock = Integer.parseInt(data);
                    if (stock > 0) {
                        //扣减库存
                        stock--;
                        curatorFramework.setData().forPath(dataPath, (stock + "").getBytes());
                    }
                    return stock;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
        if (result == null) {
            log.info("业务执行失败");
            return "业务执行失败";
        } else {
            log.info("执行成功,剩余库存:" + result);
            return "执行成功,剩余库存:" + result;
        }
    }

    /**
     * 获取分布式ID
     * @param path
     * @param data
     * @return
     * @throws Exception
     */
    public String getDistributedId(String path, String data) throws Exception {
        String seqNode = this.createTypeSeqNode(CreateMode.EPHEMERAL_SEQUENTIAL, path, data);
        System.out.println(seqNode);
        int index = seqNode.lastIndexOf(path);
        if (index >= 0) {
            index += path.length();
            return index <= seqNode.length() ? seqNode.substring(index) : "";
        }
        return seqNode;
    }

    /**
     * 创建指定类型的有序节点
     * @param nodeType
     * @param path
     * @param data
     * @return
     */
    public String createTypeSeqNode(CreateMode nodeType, String path, String data) throws Exception {
        String nodePath = curatorFramework.create().creatingParentsIfNeeded().withProtection().withMode(nodeType)
                .forPath(path, data.getBytes(StandardCharsets.UTF_8));
        return nodePath;
    }


}

package com.cxb.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootHelloApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootHelloApplication.class, args);
    }

}

 

代码地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用Apache Curator库来实现Java使用Zookeeper实现分布式锁Curator提供了一个InterProcessMutex类来实现分布式锁。 下面是一个简单的示例代码: ```java import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.locks.InterProcessMutex; import org.apache.curator.retry.ExponentialBackoffRetry; // 创建 CuratorFramework 实例 CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new ExponentialBackoffRetry(1000, 3)); client.start(); // 创建分布式锁 InterProcessMutex lock = new InterProcessMutex(client, "/locks/my_lock"); // 获取锁 lock.acquire(); try { // 在此处执行临界代码 } finally { // 释放锁 lock.release(); } ``` 请注意,上面的代码是示例,在生产环境中应该使用try-with-resources语句来确保锁能正确释放。 ### 回答2: 实现Zookeeper分布式锁Java代码步骤如下: 1. 引入ZooKeeper的相关依赖:在项目的pom.xml文件中添加ZooKeeper依赖。 2. 创建一个ZooKeeper连接:使用ZooKeeper提供的API创建与ZooKeeper服务器的连接。 3. 创建锁节点:在ZooKeeper中创建一个永久节点作为锁节点。 4. 尝试获取锁:在需要获取锁的代码处,使用ZooKeeper的create()方法创建一个临时顺序节点。 5. 获取当前所有的锁节点使用ZooKeeper的getChildren()方法获取锁节点的子节点。 6. 判断当前节点是否为最小的节点:比较当前节点和获取到的所有节点中最小的节点,如果当前节点是最小的节点,则表示获取到了分布式锁。 7. 如果当前节点不是最小的节点,则监听前一个节点的删除事件。 8. 如果前一个节点被删除,则再次检查当前节点是否是最小节点。如果是,则获取到了分布式锁。 9. 当前节点没有获取到锁时,使用ZooKeeper的exists()方法对前一个节点进行监听。 10. 当获取到锁后执行相应的业务逻辑。 11. 业务逻辑执行完毕后,通过删除当前节点释放锁。 12. 关闭ZooKeeper连接。 以上是一个基本实现分布式锁的框架,可以根据具体业务需求进行相应的优化和改进。 ### 回答3: 实现Zookeeper分布式锁需要以下步骤: 1. 创建Zookeeper连接:使用ZooKeeper类初始化Zookeeper连接,指定Zookeeper服务器的地址和超时时间。 2. 创建锁节点使用create方法在Zookeeper上创建一个持久顺序节点来作为锁节点。这里需要考虑到可能的并发性,可以使用ThreadID等加前缀构建有序节点的名称。 3. 获取锁:使用getChildren方法获取当前所有的锁节点,然后判断自己创建的锁节点是否是最小节点。如果是最小节点,表示成功获取锁,执行相应逻辑;否则,监听前一个节点的删除事件。 4. 监听前一个节点的删除事件:在获取锁失败的情况下,使用exist方法对前一个节点进行监听。当前一个节点被删除后,重新尝试获取锁。 5. 释放锁:执行完逻辑后,使用delete方法删除自己创建的锁节点,释放资源。 示例代码如下: ```java import org.apache.zookeeper.*; import org.apache.zookeeper.data.Stat; import java.io.IOException; import java.util.List; import java.util.concurrent.CountDownLatch; public class ZookeeperLock { private ZooKeeper zooKeeper; private CountDownLatch countDownLatch; private static final String ZOOKEEPER_ADDRESS = "localhost:2181"; private static final int SESSION_TIMEOUT = 5000; private static final String LOCK_NODE = "/lock"; public ZookeeperLock() { try { zooKeeper = new ZooKeeper(ZOOKEEPER_ADDRESS, SESSION_TIMEOUT, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == Event.KeeperState.SyncConnected) { countDownLatch.countDown(); } } }); countDownLatch.await(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } createLockNode(); } private void createLockNode() { try { zooKeeper.create(LOCK_NODE, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } catch (KeeperException | InterruptedException e) { e.printStackTrace(); } } public void lock() { String lockNode = null; try { lockNode = zooKeeper.create(LOCK_NODE + "/", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); List<String> list = zooKeeper.getChildren(LOCK_NODE, false); String minNode = getMinNode(list); if (lockNode.equals(LOCK_NODE + "/" + minNode)) { // get the lock System.out.println("Lock acquired"); } else { Stat stat = zooKeeper.exists(LOCK_NODE + "/" + minNode, true); if (stat != null) { synchronized (stat) { stat.wait(); } } } } catch (KeeperException | InterruptedException e) { e.printStackTrace(); } } public void unlock() { try { zooKeeper.delete(LOCK_NODE + "/", -1); } catch (KeeperException | InterruptedException e) { e.printStackTrace(); } } private String getMinNode(List<String> list) { String minNode = list.get(0); for (String node : list) { if (node.compareTo(minNode) < 0) { minNode = node; } } return minNode; } } ``` 以上是一个简单的使用Java代码实现Zookeeper分布式锁的例子。在lock方法中,当获取到锁后,会打印"Lock acquired",当释放锁后,可以继续执行后续逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值