Zookeeper 4 Zookeeper JavaAPI 操作 4.9 模拟12306 售票案例

该博客介绍了如何使用Zookeeper的Curator框架实现分布式锁,通过模拟12306售票场景,展示了如何解决并发问题。文章详细讲解了InterProcessMutex分布式排它锁的使用,并提供了Java代码示例,演示了加锁和解锁的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Zookeeper

【黑马程序员Zookeeper视频教程,快速入门zookeeper技术】

4 Zookeeper JavaAPI 操作

4.9 模拟12306 售票案例
4.9.1 Curator 实现分布式锁 API

在Curator中有五种锁方案:

  • InterProcessSemaphoreMutex:分布式排它锁(非可重入锁)
  • InterProcessMutex:分布式可重入排它锁
  • InterProcessReadWriteLock:分布式读写锁
  • InterProcessMultiLock:将多个锁作为单个实体管理的容器
  • InterProcessSemaphoreV2:共享信号量
4.9.2 分布式锁案例 - 模拟12306 售票

在这里插入图片描述

平时我们 用这些,它们其实都不是 真正出票 的,它们只是代理商

12306 才是真正的出票 的

在这里插入图片描述

12306 不多解释,那个请求量,单机…,肯定会搭 集群的

在这里插入图片描述

代理商访问 12306, 然后12306 访问自己的 数据库【当然数据库 也会做成集群,对外访问接口一个】

资源在谁那儿,分布式锁 就加到 谁那儿,所以肯定是在 12306 上加

在这里插入图片描述

引入Zookeeper 后,12306 就可以作为 Zookeeper 的客户端 【分布式锁 由Zookeeper 提供】

【简单模拟】

先来一个票类

package com.dingjiaxiong.curator;

/**
 * ClassName: Ticket12306
 * date: 2022/11/15 15:18
 *
 * @author DingJiaxiong
 */


public class Ticket12306 implements Runnable{

    private int tickets = 10; //数据库的票数

    @Override
    public void run() {

        //一直对外提供服务
        while (true){
            if (tickets > 0){

                System.out.println(Thread.currentThread() + ":" + tickets);
                tickets --;
            }
        }

    }
}

来一个 新的测试类

package com.dingjiaxiong.curator;

/**
 * ClassName: LockTest
 * date: 2022/11/15 15:17
 *
 * @author DingJiaxiong
 */


public class LockTest {

    public static void main(String[] args) {

        Ticket12306 ticket12306 = new Ticket12306();

        //创建客户端【买票的】
        Thread t1 = new Thread(ticket12306,"携程");
        Thread t2 = new Thread(ticket12306,"飞猪");

        t1.start();
        t2.start();
    }
}

现在直接运行就会 产生 并发问题,看看结果

在这里插入图片描述

很明显这样是不行的

【现在就给 它加上分布式 锁】

package com.dingjiaxiong.curator;

import org.apache.curator.RetryPolicy;
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;

import java.util.concurrent.TimeUnit;

/**
 * ClassName: Ticket12306
 * date: 2022/11/15 15:18
 *
 * @author DingJiaxiong
 */


public class Ticket12306 implements Runnable {

    private int tickets = 10; //数据库的票数

    private InterProcessMutex lock;

    public Ticket12306() {

        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);

        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("zookeeper的IP :2181")
                .sessionTimeoutMs(60 * 1000)
                .connectionTimeoutMs(15 * 1000)
                .retryPolicy(retryPolicy)
                .build();

        client.start();

        lock = new InterProcessMutex(client, "/lock");
    }

    @Override
    public void run() {

        //一直对外提供服务
        while (true) {
            //加个【获取】锁
            try {
                lock.acquire(3, TimeUnit.SECONDS);
                if (tickets > 0) {

                    System.out.println(Thread.currentThread() + ":" + tickets);
                    tickets--;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 释放锁
                try {
                    lock.release();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

OK,直接重新运行测试类

在这里插入图片描述

这下就不会 冲了

看看命令行 客户端

在这里插入图片描述

多看几次

在这里插入图片描述

就是我们 之前说的 使用临时顺序节点实现的东西

【那就这样吧】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ding Jiaxiong

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

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

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

打赏作者

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

抵扣说明:

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

余额充值