Zookeeper实战分布式锁

Posted wang01

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zookeeper实战分布式锁相关的知识,希望对你有一定的参考价值。

 

年 月 日 时 分 秒 序号

技术图片

 

 案例

订单产生的类
技术图片
public class OrderNumber {
    private static Integer number=0;
    //生成订单号
    public String getNumber(){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        ++number;
        return sdf.format(new Date())+"	"+number;
    }
}
技术图片
订单业务处理类
技术图片
public class OrderService implements Runnable{
    private static OrderNumber orderNumber=new OrderNumber();
    private Lock lock=new ZkLockImpl();



    //生成订单
    public void getOrderNumber(){
        //同步代码块:多个线程访问同一个资源时
        /*synchronized (orderNumber){

        }*/


        //获取锁
        lock.getLock();
        System.out.println("当前生成的订单编号为:"+orderNumber.getNumber());
        //释放锁
        lock.unLock();

    }

    @Override
    public void run() {
        getOrderNumber();
    }

    public static void main(String[] args) {
        //生成100个线程
        for(int i=1;i<=10000;i++){
            new Thread(new OrderService()).start();
        }
    }
}
技术图片
锁接口
技术图片
public interface Lock {
    //获取锁
    public void getLock();


    //释放锁
    public void unLock();

}
技术图片

实现Lock接口

技术图片
public abstract class ZookeeperLock implements Lock{
    /**
     * 创建zkClient连接对象
     */
    private static final String ZK_ADDRESS="0.0.0.0:2181";

    protected ZkClient zkClient=new ZkClient(ZK_ADDRESS);


    /**
     * 每一个进程在创建节点时,实际上就是获得了一把锁,如果在获取锁是发现返回值为true,代表当前没有锁,我可以使用,如果返回值为false,代表锁正在被占用,那么我只能等待
     * @return
     */
    @Override
    public void getLock() {
        //获取一把锁
        if(tryLock()){
            System.out.println("获取到锁资源");
        }else{
            //当返回值为false时,代表当前锁正在被使用,等待
            waitLock();
            //等待之后我得再次获取,我不再次获取我怎么能得到锁资源
            getLock();
        }

    }


    /**
     * 释放锁,zk关闭
     */
    @Override
    public void unLock() {
        if(zkClient!=null){
            zkClient.close();
        }
    }


    //获取锁资源
    public abstract boolean tryLock();


    //等待
    public abstract void waitLock();
}
技术图片
获取锁和释放锁真正实现的类
技术图片
public class ZkLockImpl extends ZookeeperLock{
    private CountDownLatch countDownLatch = null;


    @Override
    public boolean tryLock() {
        try {
            //创建临时节点
            zkClient.createEphemeral("/zkTemp");
            return true;
        }catch (Exception ex){
            return false;
        }
    }

    @Override
    public void waitLock() {
        //监听节点是否是删除了
        IZkDataListener iZkDataListener=new IZkDataListener() {
            @Override
            public void handleDataChange(String s, Object o) throws Exception {

            }

            @Override
            public void handleDataDeleted(String s) throws Exception {
                if(countDownLatch!=null){
                    //释放掉
                    countDownLatch.countDown();
                }
            }
        };

        //如果已经存在zkTemp节点,就等待
        if(zkClient.exists("/zkTemp")){
            countDownLatch=new CountDownLatch(1);
            System.out.println("订单号重复,请等待=================================");
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

以上是关于Zookeeper实战分布式锁的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot电商项目实战 — Redis实现分布式锁

SpringBoot电商项目实战 — Zookeeper的分布式锁实现

分布式锁三大技术方案实战——基于zookeeper方式实现分布式锁

《大厂高并发分布式锁从入门到实战》第4讲之Zookeeper分布式锁

Zookeeper实战分布式锁

Redis实现分布式锁(设计模式应用实战)