java的锁和zookeeper的锁

java

java的锁属于单机的锁,也就是部署一个实例,这个锁只能控制该程序中的资源。

公平锁

使用方式

    @Test
    private void TestLock(){
        ReentrantLock reentrantLock = new ReentrantLock(true);
        //加锁
        reentrantLock.lock();
        //解锁
        reentrantLock.unlock();
    }

非公平锁

使用方式

    @Test
    private void TestLock(){
        ReentrantLock reentrantLock = new ReentrantLock();
        //加锁
        reentrantLock.lock();
        //解锁
        reentrantLock.unlock();
    }

zookeeper

zookeeper的锁属于分布式的锁,也就是它可以控制多台机器的资源使用。
zookeeper的锁其实是通过创建临时节点来实现的。下面说一下原理。
假设我们现在有一个永久节点 /lock

公平锁

其实就是每个需要获取锁的线程,去/lock节点下去创建相同前缀的临时顺序子节点,比如templock-,编号最小的那个节点,表示获得了锁。

获取锁

所以,每个线程在尝试占用锁之前,首先判断自己是排号是不是当前最小,如果是,则获取锁。

释放锁

释放锁的时候,删除创建的Znode。

排队中的任务获取锁

每一个等通知的Znode节点,只需要监听(linsten)或者监视(watch)排号在自己前面的节点,等待其删除事件,当获取到删除事件,判断一次自己是否是最小的节点,是的话,就获取到了锁。

非公平锁

非公平锁不使用顺序节点,每个需要获取锁的线程,创建同一个短暂无时序性的节点路径,比如tmplock节点。

获取锁

创建成功的程序获取锁,当一个程序,得到锁时,其他程序,只能监听,不能再次创建。

释放锁

释放锁的时候,删除创建的Znode。

其他程序获取锁

当监听到tmplock被删除,其他锁可以重复获取锁的过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答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",当释放后,可以继续执行后续逻辑。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盖丽男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值