Zookeeper lock

获得锁:
1.创建根节点"/root"
2.在根节点下新建子节点"/root/c-xxxxxx",SEQUENTIAL模式
3.对根节点调用getChildren(),如果第2步创建的节点是所有子节点中序号最小的,则获得锁;否则进入第4步
4.在序号最小的子节点上调用exists(),当序号最小的子节点被删除后返回第3步

释放锁:

删除自己创建的子节点即可

package com.lock;

/**
 * Created by bcm on 15-3-13.
 */
import java.io.IOException;
import java.net.InetAddress;
import java.util.List;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class Locks implements Watcher{

    static ZooKeeper zk=null;
    static Integer mutex=null;
    String name=null;
    String path=null;

    @Override
    synchronized public void process(WatchedEvent event) {
        System.out.println("process:"+event.toString());
        synchronized(mutex){
            mutex.notify();
        }
    }

    Locks(String address){
        try{
            zk=new ZooKeeper(address,30000000,this);
//            zk.create("/lock", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            mutex=new Integer(-1);
            name = new String(InetAddress.getLocalHost().getCanonicalHostName().toString());
        }catch(IOException e){
            zk=null;
        }
//        catch (KeeperException e) {
//            e.printStackTrace();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
    }

    private String  minSeq(List<String> list){
        int min=Integer.parseInt(list.get(0).substring(11));
        String minString ="";
        minString =  list.get(0).substring(11);
        for(int i=1;i<list.size();i++){
            if(min>Integer.parseInt(list.get(i).substring(11))){
                min=Integer.parseInt(list.get(i).substring(11));
                minString = list.get(i).substring(11);
            }
        }
        return minString;
    }

    boolean getLock() throws KeeperException, InterruptedException{
        //create方法返回新建的节点的完整路径
        path=zk.create("/lock/"+name+"-", new byte[0], Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT_SEQUENTIAL);
        String minStr;
        while(true){
            synchronized(mutex){
                List<String> list=zk.getChildren("/lock", true);
                minStr=minSeq(list);
                //如果刚建的节点是根节点的所有子节点中序号最小的,则获得了锁,可以返回true
                if(Integer.parseInt(minStr)==Integer.parseInt(path.substring(17))){
                    return true;
                }else{
                    mutex.wait();       //等待事件(新建节点或删除节点)发生
                    while(true){
                       zk.getChildren("/lock", true); //必须再注册watcher,以便监听znode节点。
                        Stat s=zk.exists("/lock/"+name+"-"+minStr, true);      //查看序号最小的子节点还在不在
                        if(s!=null)     //如果还在,则继续等待事件发生
                            mutex.wait();
                        else            //如果不在,则跳外层循环中,查看新的最小序号的子节点是谁
                            break;
                    }
                }
            }
        }
    }

    boolean releaseLock() throws KeeperException, InterruptedException{
        if(path!=null){
            zk.delete(path, -1);
            path=null;
        }
        return true;
    }

    public static void main(String []args) throws KeeperException, InterruptedException{
        Locks lock1=new Locks("localhost:2181");
        if(lock1.getLock()){
            System.out.println("T1 Get lock at "+System.currentTimeMillis());
            for(int i=0;i<1000;++i)
                Thread.sleep(5000);
            lock1.releaseLock();
        }
        Locks lock2=new Locks("localhost:2181");
        if(lock2.getLock()){
            System.out.println("T2 Get lock at "+System.currentTimeMillis());
            lock2.releaseLock();
        }
    }

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值