Based zk "temporary order of nodes" distributed lock

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

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * Created by zzq on 2019/6/25.
 * / 
Public  class ZKLock the implements Watcher {
     Private ZooKeeper ZK;
     // current lock 
    Private String currentLock;
     // Resource Name 
    Private String LockName;
     // lock root 
    Private String ROOT_LOCK = "/ root_lock" ;
     // lock root of each resource 
    Private String tmpRootLock;
     // Since zookeeper monitor node status will return immediately, so it is necessary to use CountDownLatch (other mechanisms such as semaphores can be used) 
    Private CountDownLatch LATCH;

    public ZKLock(String zkAddress, String lockName) {
        this.lockName = "" + System.nanoTime();
        try {
            zk = new ZooKeeper(zkAddress, 30000, this);
            createZNode(ROOT_LOCK, CreateMode.PERSISTENT);
            tmpRootLock = ROOT_LOCK + "/" + lockName;
            createZNode (tmpRootLock, CreateMode.PERSISTENT); // can not create a temporary order of the nodes under node provisional **** zk 
        } the catch (IOException E) {
            e.printStackTrace ();
        } catch (KeeperException e) {
            e.printStackTrace ();
        } catch (InterruptedException e) {
            e.printStackTrace ();
        }
    }

    Private  void createZNode (Node String, CreateMode MODE) throws KeeperException, InterruptedException {
         // Get the root node status 
        Stat STAT = zk.exists (Node, to false );
         // if the root node does not exist, create a root node type persistent node 
        IF (STAT == null ) {
            zk.create(node, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, mode);
        }
    }

    public  void Lock () {
         the try {
             // Create a temporary order of the nodes under the root node, the node returns the value of the path created 
            currentLock = zk.create (tmpRootLock + "/" + LockName, new new  byte [0 ],
                    ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
            // Get all provisional order of the nodes below the root node, the monitor is not provided 
            List <String> = zk.getChildren Children (tmpRootLock, to false );
             // for all the nodes in the temporal order from small to large root node 
            children.sort ( null );
             // determine whether the current node is the smallest node, if it is to acquire the lock, if not, to find their own previous node, monitoring its present state 
            int curIndex = children.indexOf (currentLock.substring (currentLock.lastIndexOf ( "/") +. 1 ));
             IF (curIndex = 0! ) {
                 // get the path of a node before the current 
                String PREV = children.get (curIndex -. 1 );
                 // listener before a state of the current node , null if the node does not exist
                Zk.exists STAT = STAT (tmpRootLock + "/" + PREV, to true );
                 // Here again determines whether the node exists 
                IF (! STAT = null ) {
                    LATCH = new new a CountDownLatch (. 1 );
                     // enters a wait state lock 
                    latch.await ();
                    latch = null;
                }
            }
        } catch (KeeperException e) {
            e.printStackTrace ();
        } catch (InterruptedException e) {
            e.printStackTrace ();
        }
    }

    // release the lock 
    public  void UNLOCK () {
         the try {
             // node delete created 
            zk.delete (currentLock, -1 );
            List<String> children = zk.getChildren(tmpRootLock, false);
            if (children.size() == 0) {
                zk.delete (tmpRootLock, -1 );
                 // Close zookeeper connected 
                zk.close ();
            }
        } catch (InterruptedException e) {
            e.printStackTrace ();
        } catch (KeeperException e) {
            e.printStackTrace ();
        }
        currentLock = null;
    }

    @Override
    public void process(WatchedEvent event) {
        if (this.latch != null) {
            latch.countDown();
        }
    }

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 7; i++) {
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    ZKLock lock = new ZKLock("10.10.210.123:2181", "lock");
//                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                    lock.lock();
//                }
//            }).start();
        }
        ZKLock lock = new ZKLock("10.10.210.123:2181", "L1");
        lock.lock();

        ZKLock lock1 = new ZKLock("10.10.210.123:2181", "L2");
        lock1.lock();
        lock1.unlock();

        lock.unlock();
        String uu = "";
    }
}

 

Guess you like

Origin www.cnblogs.com/zzq-include/p/11083537.html