zookeeper (iv) Implementation of Distributed Lock

zookeeper achieve Distributed Lock

The principle

According to the characteristics zookeeper nodes, can be created by creating a temporary order node exclusive lock.
FIFO queue

  1. Gets all the child nodes under the specified root node, the child node is the task getChildren
  2. In order to determine their child nodes of node
  3. If it is not the smallest child node, then the monitor than on their own smaller one child, or in a waiting
  4. Watcher notifications received, the process is repeated

The introduction of pom

 <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.4.8</version>
    </dependency>
public class MyDistributeLock {

    private  ZooKeeper zooKeeper;
    private static final String ROOT_LOCKS="/LOCKS";//根节点
    private final static String CONNECTSTRING="182.92.73.88:2181";
    private final static byte[] data={1,2}; //节点的数据
    private CountDownLatch countDownLatch=new CountDownLatch(1);
    private  int sessionTimeout=5000;
    private String lockID; //记录锁节点id
    public MyDistributeLock(){
        this.zooKeeper=getInstance();
    }


    private ZooKeeper getInstance()  {

        final CountDownLatch countDownLatch1=new CountDownLatch(1);
        ZooKeeper zooKeeper= null;
        try {
            zooKeeper = new ZooKeeper(CONNECTSTRING, sessionTimeout, new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                   if(event.getState()==Event.KeeperState.SyncConnected){
                       countDownLatch1.countDown();
                   }
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return zooKeeper;
    }



    public void lock() throws KeeperException, InterruptedException {
        lockID=zooKeeper.create(ROOT_LOCKS+"/",data, ZooDefs.Ids.
                OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        List<String> childrenNodes=zooKeeper.getChildren(ROOT_LOCKS,true);//获取根节点下的所有子节点
        //排序,从小到大
        SortedSet<String> sortedSet=new TreeSet<String>();
        for(String children:childrenNodes){
            sortedSet.add(ROOT_LOCKS+"/"+children);
        }

        String first=sortedSet.first();
        if(lockID.equals(first)){
            System.out.println(Thread.currentThread().getName()+"->成功获得锁,lock节点为:["+lockID+"]");
            return;
        }

        SortedSet<String> lessThanLockId=sortedSet.headSet(lockID);
        if(!lessThanLockId.isEmpty()){
            String preid=lessThanLockId.last();
            zooKeeper.exists(preid,new MyWatcher(countDownLatch));
            countDownLatch.await(sessionTimeout, TimeUnit.MILLISECONDS);
            System.out.println(Thread.currentThread().getName()+"->成功获得锁,lock节点为:["+lockID+"]");
        }

    }
    public void unlock(){
        //System.out.println(Thread.currentThread().getName()+"->开始释放锁:["+lockID+"]");
        try {
            zooKeeper.delete(lockID,-1);
            //System.out.println("节点["+lockID+"]成功被删除");

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        final CountDownLatch latch=new CountDownLatch(10);
        final Random random=new Random();
        for(int i=0;i<10;i++){
           new Thread(new Runnable() {
               @Override
               public void run() {
                   MyDistributeLock lock=null;
                   try {
                       lock=new MyDistributeLock();
                       latch.countDown();
                       latch.await();
                       lock.lock();
                       Thread.sleep(random.nextInt(500));
                   } catch (Exception e) {
                       e.printStackTrace();
                   } finally {
                       if(lock!=null){
                           lock.unlock();
                       }
                   }
               }

           }).start();
        }
    }

}

public class MyWatcher implements Watcher {

    CountDownLatch countDownLatch;
    public MyWatcher(CountDownLatch countDownLatch){
        this.countDownLatch=countDownLatch;
    }

    @Override
    public void process(WatchedEvent event) {
        if(event.getType()== Event.EventType.NodeDeleted){
            countDownLatch.countDown();
        }
    }
}

Published 40 original articles · won praise 6 · views 1523

Guess you like

Origin blog.csdn.net/qq_26737667/article/details/104405066