Distributed lock zookeeper

package zk.lock;

 

import java.util.Collections;

import java.util.List;

import java.util.concurrent.CountDownLatch;

 

import org.apache.zookeeper.CreateMode;

import org.apache.zookeeper.WatchedEvent;

import org.apache.zookeeper.Watcher;

import org.apache.zookeeper.Watcher.Event.EventType;

import org.apache.zookeeper.Watcher.Event.KeeperState;

import org.apache.zookeeper.ZooDefs.Ids;

import org.apache.zookeeper.ZooKeeper;

import org.apache.zookeeper.data.Stat;

 

public class ZkDistributedClient {

    // overtime time

    private static final int SESSION_TIMEOUT = 5000;

    // list of zookeeper servers

    private String hosts = "127.0.0.1:2181";

    private String groupNode = "locks1";

    //private String subNode = "sub";

 

    private ZooKeeper zk;

    // The child node created by the current client

    private String thisPath;

    // The child node that the current client is waiting for

    private String waitPath;

 

    private CountDownLatch latch = new CountDownLatch(1);

//return result

    public String result =null;

    /**

     * Connect to zookeeper

     * subNode temporary node header

     * data data

     */

    public String  connectZookeeper(String subNode,String data) throws Exception {

    final String fdata = date;

   

   

        zk = new ZooKeeper(hosts, SESSION_TIMEOUT, new Watcher() {

            public void process(WatchedEvent event) {

                try {

                    // When the connection is established, open the latch and wake up the thread waiting on the latch

                    if (event.getState() == KeeperState.SyncConnected) {

 

                    latch.countDown();

                    }

 

                 // The delete event of waitPath occurred

                    if (event.getType() == EventType.NodeDeleted && event.getPath().equals(waitPath)) {

                    // Check if thisPath is really the smallest node in the list

                    List<String> childrenNodes = zk.getChildren("/" + groupNode, false);

                    String thisNode = thisPath.substring(("/" + groupNode + "/").length());

                    // sort

                    Collections.sort(childrenNodes);

                    int index = childrenNodes.indexOf(thisNode);

                    if (index == 0) {

                    // is indeed the smallest node

                    String t = doSomething(fdata);

                    System.out.println("watch:::"+t);

                    result = t;

                    } else {

                    // Explain that waitPath is hung up due to an exception

                    // update waitPath

                    waitPath = "/" + groupNode + "/" + childrenNodes.get(index - 1);

                    // Re-register the listener, and determine whether the waitPath has been deleted at this time

                    if (zk.exists(waitPath, true) == null) {

                    String tt = doSomething (trusted);

                   

                    System.out.println("watch===watch:::"+tt);

                    result = tt;

                    }

                    }

                    }

                    

                } catch (Exception e) {

                    e.printStackTrace ();

                }

            }

        });

 

        // wait for the connection to be established

        latch.await();

 

        // create child nodes

        thisPath = zk.create("/" + groupNode + "/" + subNode, null, Ids.OPEN_ACL_UNSAFE,

                CreateMode.EPHEMERAL_SEQUENTIAL);

 

        // wait for a while to make the result clearer

        Thread.sleep(10);

 

        // Note that it is not necessary to monitor the changes of the child nodes of "/locks"

        List<String> childrenNodes = zk.getChildren("/" + groupNode, false);

        

 

        // There is only one child node in the list, that must be thisPath, indicating that the client has obtained the lock

        if (childrenNodes.size() == 1) {

           return  doSomething(data);

        } else {

            String thisNode = thisPath.substring(("/" + groupNode + "/").length());

            System.out.println(thisNode +"--------------");

            // sort

            Collections.sort(childrenNodes);

            int index = childrenNodes.indexOf(thisNode);

            if (index == -1) {

                // never happened

            } else if (index == 0) {

                // inddx == 0, indicating that thisNode is the smallest in the list, and the current client obtains the lock

              return  doSomething(data);

            } else {

                // Get the node that ranks 1st before thisPath

                this.waitPath = "/" + groupNode + "/" + childrenNodes.get(index - 1);

                // Register the listener on waitPath, when waitPath is deleted, zookeeper will call back the listener's process method

                zk.getData(waitPath, true, new Stat());

                

                return null;

            }

        }

        

        return null;

    }

 

    private String doSomething(String data) throws Exception {

        try {

            System.out.println("gain lock: " + thisPath+"----"+data);

            byte[] by= zk.getData("/locknum", null, null);

            String num = new String(by);

            System.out.println(num+" :::::current value----------------------------");

            Integer newNum = Integer.parseInt(num) -1;

            zk.setData("/locknum", newNum.toString().getBytes(), -1);

            System.out.println(newNum+":::::final value----------------------------");

 

            

            Thread.sleep(2000);

            // do something

        } finally {

            System.out.println("finished: " + thisPath);

            // Delete thisPath, the client listening to thisPath will be notified

            // Equivalent to releasing the lock

            zk.delete(this.thisPath, -1);

         

        }

        

        return data;

    }

    

    

 

    

    public static void main(String[] args) throws Exception {

        for (int i = 0; i < 5; i++) {

            new Thread() {

                public void run() {

                    try {

                        ZkDistributedClient dl = new ZkDistributedClient();

                       String s = dl.connectZookeeper("gao","test");

                        System.out.println("return-=========="+s);

                        System.out.println("return========================"+dl.result);

                    } catch (Exception e) {

                        e.printStackTrace ();

                    }

                }

            }.start();

        }

 

        Thread.sleep(Long.MAX_VALUE);

    

        

    }

}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326518705&siteId=291194637