zoukankan      html  css  js  c++  java
  • 【zookeeper】利用zookeeper实现分布式锁

    手写zookeeper分布式锁,测试生成订单编号

    1.生成订单编号工具类

    /**
     * TODO
     *
     * @author CSD
     * @date 2021-09-09 13:51
     * 订单编号工具类
     */
    public class OrderNumCreateUtil {
    
        private static int number = 0;
    
        /**
         * 生成订单编号
         * @return
         */
        public String getNumber(){
            return String.valueOf(++number);
        }
    }

    2.订单业务类

    /**
     * TODO
     * 订单业务类
     * @author CSD
     * @date 2021-09-09 13:54
     */
    public class OrderService {
        private OrderNumCreateUtil orderNumCreateUtil = new OrderNumCreateUtil();
    
        private ZkLock zkLock = new ZkDistributedLock();
        public void getOrdNumber() {
            zkLock.zklock();
            try {
                String number = orderNumCreateUtil.getNumber();
                System.out.println("number = " + number);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                zkLock.zkUnlock();
            }
        }
    }

    3.zookeeper接口

    /**
     * TODO
     *
     * @author CSD
     * @date 2021-09-09 14:05
     */
    public interface ZkLock {
    
        public void zklock();
        public void zkUnlock();
    }

    4. 使用模板设计模式把共用的代码抽离父类

    /**
     * TODO
     *
     * @author CSD
     * @date 2021-09-09 14:07
     */
    public abstract class ZkAbstractTemplateLock implements ZkLock {
    
        protected String path = "/zkLock";
        protected CountDownLatch countDownLatch = null;
        public static final String ZKSERVER = "172.22.83.153:2181";
        public static final Integer TIME_OUT = 45 * 1000;
        ZkClient zkClient = new ZkClient(ZKSERVER,TIME_OUT);
        @Override
        public void zklock() {
            if(tryZkLock()){
                System.out.println("线程"+Thread.currentThread().getName()+":获得锁
    ");
            }else{
                waitZkLock();
                zklock();
            }
        }
    
        public abstract void waitZkLock();
    
        public abstract boolean tryZkLock();
    
        @Override
        public void zkUnlock() {
            if (zkClient != null){
                zkClient.close();
            }
            System.out.println("线程"+Thread.currentThread().getName()+"释放锁
    
    ");
        }
    }

    5.zk分布式锁具体的实现类

    /**
     * TODO
     *
     * @author CSD
     * @date 2021-09-09 14:22
     */
    public class ZkDistributedLock extends ZkAbstractTemplateLock{
    
        @Override
        public void waitZkLock() {
            IZkDataListener iZkDataListener = new IZkDataListener() {
                @Override
                public void handleDataChange(String dataPath, Object data)  {
    
                }
    
                @Override
                public void handleDataDeleted(String dataPath){
                    if (countDownLatch != null){
                        countDownLatch.countDown();
                    }
                }
            };
    
            zkClient.subscribeDataChanges(path,iZkDataListener);
            if (zkClient.exists(path)){
                countDownLatch = new CountDownLatch(1);
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            zkClient.unsubscribeDataChanges(path,iZkDataListener);
        }
    
        @Override
        public boolean tryZkLock() {
            try {
                zkClient.createEphemeral(path);
                return true;
            } catch (Exception e){
                return false;
            }
        }
    }

    6.开启10个线程测试

    /**
     * TODO
     *
     * @author CSD
     * @date 2021-09-09 13:57
     */
    public class Client {
        public static void main(String[] args) {
            for (int i = 0; i < 50; i++) {
                new Thread(()->{
                    new OrderService().getOrdNumber();
                },String.valueOf(i)).start();
            }
        }
    }

    7.运行结果

    线程6:获得锁
    
    number = 1
    线程6释放锁
    
    
    线程1:获得锁
    
    number = 2
    线程1释放锁
    
    
    线程5:获得锁
    
    number = 3
    线程5释放锁
    
    
    线程8:获得锁
    
    number = 4
    线程8释放锁
    
    
    线程2:获得锁
    
    number = 5
    线程2释放锁
    
    
    线程4:获得锁
    
    number = 6
    线程4释放锁
    
    
    线程0:获得锁
    
    number = 7
    线程0释放锁
    
    
    线程7:获得锁
    
    number = 8
    线程7释放锁
    
    
    线程3:获得锁
    
    number = 9
    线程3释放锁
    
    
    线程9:获得锁
    
    number = 10
    线程9释放锁

    8.所用的maven依赖

    <dependency>
         <groupId>com.github.sgroschupf</groupId>
         <artifactId>zkclient</artifactId>
         <version>0.1</version>
    </dependency>
  • 相关阅读:
    main函数的实现解析
    srand()和rand()函数的使用
    shell编程总结
    自动创建字符设备,不需mknod
    linux使用i/o内存访问外设
    Flink之state processor api原理
    Flink之state processor api实践
    软件架构被高估,清晰简单的设计被低估
    技术架构的战略和战术
    Flink task之间的数据交换
  • 原文地址:https://www.cnblogs.com/aioe/p/15247071.html
Copyright © 2011-2022 走看看