Zookeeper分布式锁

package com.yf.test.demo;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class DistributedLock implements Watcher,Lock {

    static int timeout=4000;
    private String lockName;
    //定义锁的根结点
    static String ROOT_LOCK="/dlocks";

    //定义阻塞线程的型号量
    CountDownLatch latch=null;

    //定义一个存储zk对象
    ZooKeeper zk=null;

    //定义当前锁的变量
    private String currentLock;

    //定义存储等待锁的变量
    private String waitLock;

    public DistributedLock(){

    }
    public DistributedLock(String config,String lockName){
        this.lockName=lockName;
        try {
            zk=new ZooKeeper(config,timeout,this);
            //判断当前分布式锁的根结点是否存在
            Stat exists = zk.exists(ROOT_LOCK, false);
            if(exists==null){
                //创建一个永久根结点
                zk.create(ROOT_LOCK,new byte[0],ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
        }catch (Exception e){

        }

    }

    @Override
    public void process(WatchedEvent watchedEvent) {
        //监控当前有没有节点被监控,如果有就释放
        if(latch!=null){
            //放开等待锁线程
            latch.countDown();
        }
    }

    @Override
    public void lock() {
        if(tryLock()){
            System.out.println(Thread.currentThread().getName()+"get lock");
            return ;
        }else{
            waitForLock(waitLock,timeout);
        }

    }

    private void waitForLock(String waitLock,int timeout) {
        try {
            Stat stat=zk.exists(ROOT_LOCK+"/"+waitLock,false);
            if(stat!=null){
                latch=new CountDownLatch(1);
                latch.await(timeout,TimeUnit.MILLISECONDS);
                latch=null;
            }
        }catch (Exception e){

        }

    }

    @Override
    public void lockInterruptibly() throws InterruptedException {

    }

    @Override
    public boolean tryLock() {
        try {
            //拿到锁 返回
            String split="_lock_";
            currentLock=zk.create(ROOT_LOCK+"/"+lockName+split,new byte[0],ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
            //获取根结点下面的所有子节点
            List<String> list = zk.getChildren(ROOT_LOCK, false);
            //定义存储排序的集合
            List<String> nodes=new ArrayList<String>();
            for(String child:list){
                String url=child.split(split)[0];
                if(url.contains(lockName)){
                    nodes.add(child);
                }
            }
            //排序 从小到大排序
            Collections.sort(nodes);
            //判断当前节点是否是最小节点
            if(currentLock.equals(ROOT_LOCK+"/"+nodes.get(0))){
                return true;
            }
            //找到前一个节点
            String currentNodeName=currentLock.substring(currentLock.lastIndexOf("/")+1);
            int index = Collections.binarySearch(nodes, currentNodeName);
            waitLock=nodes.get(index-1);
        }catch (Exception e){
            e.printStackTrace();

        }
        return false;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }

    @Override
    public void unlock() {
        try {
            if(zk.exists(currentLock,false)!=null){
                zk.delete(currentLock,-1);
                currentLock=null;
                zk.close();
            }
        }catch (Exception e){

        }
    }

    @Override
    public Condition newCondition() {
        return null;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值