zookeeper 分布式锁实现

分布锁实现方案和优缺点先占坑
锁重入待实现!!!

//核心逻辑
tryLock():抢锁
       1 创建临时序列节点,创建后阻塞,
       2 zk.create()成功后,在回调函数中,通过zk.getChildren()获取当前根目录下序列节点,
       3 在回调函数中判断自己是否是第一节点,是则获得锁,不是,则watch前一个节点,
       4 如果前一个节点被删除,则zk.getChildren(),重复3,4步骤;
work(): 抢锁成功后的业务逻辑
unLock():释放锁

遗留问题,如何设计锁重入?

/**
 * @author haowq 2021/4/7 14:58
 */
public class WatchCallback implements Watcher, AsyncCallback.StringCallback, AsyncCallback.Children2Callback , AsyncCallback.StatCallback {
    private ZooKeeper zk;
    private String pathName;
    private String threadName;
    //Getter Setter
    private CountDownLatch latch = new CountDownLatch(1);

    public ZooKeeper getZk() {
        return zk;
    }

    public void setZk(ZooKeeper zk) {
        this.zk = zk;
    }


    public void tryLock(){
        //创建序列节点
        try {
            System.out.println(threadName + "create lock ....");
            zk.create("/lock",threadName.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,this,"AsyncCallback.StringCallback");
            //阻塞,抢锁,抢锁操作在回调函数中完成
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public void unLock(){
        try {
            zk.delete(pathName,-1);
            System.out.println(threadName + " over work....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }

    }


    public void process(WatchedEvent event) {
        //如果第一个哥们,那个锁释放了,其实只有第二个收到了回调事件!!
        //如果,不是第一个哥们,某一个,挂了,也能造成他后边的收到这个通知,从而让他后边那个跟去watch挂掉这个哥们前边的。。。
        switch (event.getType()) {
            case None:
            case NodeDataChanged:
            case NodeChildrenChanged:
            case NodeCreated:
                break;
            case NodeDeleted:
                zk.getChildren("/",false,this ,"syncCallback.Children2Callbac");
                break;
        }

    }

    // AsyncCallback.StringCallback
    @Override
    public void processResult(int rc, String path, Object ctx, String name) {
        System.out.println(name);
        pathName = name;
        //节点创建成功,需要查看自己得序列号 判断是否获得锁
        zk.getChildren(pathName,this,this,"Children2Callback");

    }


    //AsyncCallback.Children2Callbac
    @Override
    public void processResult(int rc, String path, Object ctx, List children, Stat stat) {
        //查看自己的序列
        Collections.sort(children);

        String substring = path.substring(1);
        int i = children.indexOf(substring);
        //如果序列最小 获得锁
        if(i ==0){
            //yes
            System.out.println(threadName +" i am first....");
            try {
                zk.setData("/",threadName.getBytes(),-1);
                latch.countDown();
            } catch (KeeperException | InterruptedException e) {
                e.printStackTrace();
            }
        }else{
            //Watch 上一个序列点
            zk.exists("/"+children.get(i-1),this, this,"Children2Callback");
        }

    }

    //AsyncCallback.StatCallback
    @Override
    public void processResult(int rc, String path, Object ctx, Stat stat) {

    }
}


你可能感兴趣的:(zookeeper 分布式锁实现)