zoukankan      html  css  js  c++  java
  • 使用Zookeeper实现分布式锁

    Zookeeper实现分布式锁原理

    使用zookeeper创建临时序列节点来实现分布式锁,适用于顺序执行的程序,大体思路就是创建临时序列节点,找出最小的序列节点,获取分布式锁,程序执行完成之后此序列节点消失,通过watch来监控节点的变化,从剩下的节点的找到最小的序列节点,获取分布式锁,执行相应处理,依次类推……

    Maven依赖

        <dependencies>
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.10</version>
            </dependency>
        </dependencies>

    创建Lock接口

    public interface Lock {
        //获取到锁的资源
        public void getLock();
        // 释放锁
        public void unLock();
    }

    创建ZookeeperAbstractLock抽象

    //将重复代码写入子类中..
    public abstract class ZookeeperAbstractLock implements Lock {
        // zk连接地址
        private static final String CONNECTSTRING = "127.0.0.1:2181";
        // 创建zk连接
        protected ZkClient zkClient = new ZkClient(CONNECTSTRING);
        protected static final String PATH = "/lock";
    
        public void getLock() {
            if (tryLock()) {
                System.out.println("##获取lock锁的资源####");
            } else {
                // 等待
                waitLock();
                // 重新获取锁资源
                getLock();
            }
    
        }
    
        // 获取锁资源
        abstract boolean tryLock();
    
        // 等待
        abstract void waitLock();
    
        public void unLock() {
            if (zkClient != null) {
                zkClient.close();
                System.out.println("释放锁资源...");
            }
        }
    
    }

    ZookeeperDistrbuteLock

    public class ZookeeperDistrbuteLock extends ZookeeperAbstractLock {
        private CountDownLatch countDownLatch = null;
    
        @Override
        boolean tryLock() {
            try {
                zkClient.createEphemeral(PATH);
                return true;
            } catch (Exception e) {
    //            e.printStackTrace();
                return false;
            }
    
        }
    
        @Override
        void waitLock() {
            IZkDataListener izkDataListener = new IZkDataListener() {
    
                public void handleDataDeleted(String path) throws Exception {
                    // 唤醒被等待的线程
                    if (countDownLatch != null) {
                        countDownLatch.countDown();
                    }
                }
                public void handleDataChange(String path, Object data) throws Exception {
    
                }
            };
            // 注册事件
            zkClient.subscribeDataChanges(PATH, izkDataListener);
            if (zkClient.exists(PATH)) {
                countDownLatch = new CountDownLatch(1);
                try {
                    countDownLatch.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            // 删除监听
            zkClient.unsubscribeDataChanges(PATH, izkDataListener);
        }
    
    }

    使用Zookeeper运行效果

    public class OrderService implements Runnable {
        private OrderNumGenerator orderNumGenerator = new OrderNumGenerator();
        // 使用lock锁
        // private java.util.concurrent.locks.Lock lock = new ReentrantLock();
        private Lock lock = new ZookeeperDistrbuteLock();
        public void run() {
            getNumber();
        }
        public void getNumber() {
            try {
                lock.getLock();
                String number = orderNumGenerator.getNumber();
                System.out.println(Thread.currentThread().getName() + ",生成订单ID:" + number);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unLock();
            }
        }
        public static void main(String[] args) {
            System.out.println("####生成唯一订单号###");
    //        OrderService orderService = new OrderService();
            for (int i = 0; i < 100; i++) {
                new Thread( new OrderService()).start();
            }
        }
    }
  • 相关阅读:
    PHP无限极分类
    MySQL批量插入测试数据
    MySQL常见面试知识点汇总
    小程序交易组件-自定义交易组件相关知识
    Matplotlib
    sklearn之计算回归模型的四大评价指标(explained_variance_score、mean_absolute_error、mean_squared_error、r2_score)
    pandas.core.frame.DataFrame 切片技巧
    Pyspider all 出现的坑
    mysql 问题
    爬虫遇到HTTP Error 403的问题
  • 原文地址:https://www.cnblogs.com/aaron911/p/10758384.html
Copyright © 2011-2022 走看看