基本思路,程序一启动就去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); } }