码迷,mamicode.com
首页 > 其他好文 > 详细

Zookeeper分布式锁

时间:2019-11-29 11:14:05      阅读:64      评论:0      收藏:0      [点我收藏+]

标签:思路   ble   案例   ade   bool   main   font   protect   wait   

分布式锁解决思路

  分布式锁使用zk,在zk上创建一个临时节点(有效期)

  使用临时节点作为锁,因为节点不允许重复。

  如果能创建节点成功,生成订单号,如果创建节点失败,等待。

  临时节点zk关闭,释放锁,其他节点就可以重新生成订单号。

小案例

  依赖

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

 

  OrderNumber生成订单

 

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())+"\t"+number;
    }
}

 

  OrderService打印订单号

 

public class OrderService implements Runnable{
    private static OrderNumber orderNumber=new OrderNumber();
    private Lock lock=new ZkLockImpl();

    //生成订单
    public void getOrderNumber(){
        //获取锁
        lock.getLock();
        //生成订单号
        System.out.println("订单号生成成功:"+orderNumber.getNumber());
        //释放锁
        lock.unLock();
    }


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

    public static void main(String[] args) {
        for (int i=1;i<=100;i++){
            new Thread(new OrderService()).start();
        }
    }
}

 

   Lock文接口

public interface Lock {
    //获取锁
    public void getLock();

    //释放锁
    public void unLock();
}

 

  ZookeeperLock实现

public abstract class  ZookeeperLock implements Lock{
    /**
     * 连接地址
     */
    private static final String ZK_ADDRESS="0.0.0.0:2181";


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

    @Override
    public void unLock() {
        //非等于空代表创建了订单号
        if (zkClient!=null){
            //关闭会话,删除节点
            zkClient.close();
        }
    }



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


    //等待
    public abstract void waitLock();
}

 

  ZklockImpl实现

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分布式锁

标签:思路   ble   案例   ade   bool   main   font   protect   wait   

原文地址:https://www.cnblogs.com/whtt/p/11951640.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!