zk分布式资源锁

基本思路,程序一启动就去zk注册ephemeral_sequence节点,create(true),监听为true 触发监听事件,获取字节点个数,如果为一,就去访问资源,然后删除自身,在继续创建一个新的自己,sequence递增,如果为多个,按序号小的先去dosomething(访问资源,然后删除自身),如此轮循


package zkp;

import org.apache.zookeeper.*;

import java.util.Collections;
import java.util.List;
import java.util.Random;

public class DistributedLock {
    private static final String connectString = "mini01:2181,mini02:2181,mini03:2181";
    private static final int sessionTimeout = 2000;
    private String groupNode = "locks";//父节点
    private String subNode = "sub";//序号前缀
    private boolean haveLock = false;
    private volatile String thisPath;//记录自己创建的字节点路径
    private ZooKeeper zk = null;

    //获取链接
    public void connectZookeeper() throws Exception {
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent event) {
                if (event.getType() == Event.EventType.NodeChildrenChanged && event.getPath().equals("/" + groupNode)) {
                    try {
                        List<String> childNodes = zk.getChildren("/" + groupNode, true);
                        String thisNode = thisPath.substring(("/" + groupNode + "/").length());
                        Collections.sort(childNodes);
                        if (childNodes.indexOf(thisNode) == 0) {
                            doSomething();
                            thisPath = zk.create("/" + groupNode + "/" + subNode, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

                        }
                    } catch (KeeperException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
//        程序一进来就先注册一把锁
        thisPath = zk.create("/" + groupNode + "/" + subNode, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        //wait a second 便于观察
        Thread.sleep(new Random().nextInt(1000));
        //zk的锁目录下获取所以的字节点
        List<String> childrenNodes = zk.getChildren("/" + groupNode, true);
        if (childrenNodes.size() == 1) {
            doSomething();
            thisPath = zk.create("/" + groupNode + "/" + subNode, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        }
    }

    private void doSomething() throws KeeperException, InterruptedException {
        System.out.println("gain lock: " + thisPath);
        try {
            Thread.sleep(2000);
            //doSomething
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("finished" + thisPath);
            zk.delete(this.thisPath, -1);
        }
    }

//

    public static void main(String[] args) throws Exception {
        DistributedLock dl = new DistributedLock();
        dl.connectZookeeper();
        Thread.sleep(Long.MAX_VALUE);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值