赞
踩
public class ZookeeperDistributedLock{ //测试类 public Zookeeper zk = new Zookeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183",5000 watchedEvent -> watchedEvent.getPath()); public ZookeeperDistributedLock() throws IOException {} public static void main(String[] args) throws IOException, InterruptedException, KeeperException { Zookeeper zk = new Zookeeper("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183",5000 watchedEvent -> watchedEvent.getPath()); Thread.sleep(2000); //防止连接不上zookeeper if(zk != null) { if (null == zk.exists("/member", false)) { //判断父节点是否存在 zk.create("/member/" + path, "".getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); } for (int i = 0; i < 10; i++) { new Thread(() -> { ZLock zlock = new ZLock(); boolean flg = zlock.getLock(zk,"lisi"); //获取锁 if (flg) { try { zlock.unLock(zk);//释放锁 }catch (InterruptedException e) { e.printStackTrace(); }catch (KeeperException e) { e.printStackTrace(); } } }).start(); } } } } class ZLock { //lock public String currpath; //当前的zNode public boolean getLock (Zookeeper zk, String path) { try{ String result = null; result = zk.create("/member/" + path, "".getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL); //创建临时顺序节点 List<String> list = zk.getChildren("/member",false); //获取父节点下所有子节点 Collections.sort(list);//排序 this.currpath = result; if (result.equals("/member/" + list.get(0))) { //如果是最小的就获取成功 return true; }else { CountDownLatch latch = new CountDownLatch(1); //计数阻塞 for (int i = 0; i < list.size(); i++) { if (result.equals("/member/" + ;ist.get(i))) { //找到当前所在位置 Stat stat = zk.exists("/member/" + list.get(i-1), watchedEvent -> latch.countDown()); //给前一个节点注册监听 if (stat == null) {// 可能在这一步之前 前一个节点已经被释放了,现在注册监听失败 直接获取锁成功 latch.countDown(); return true; } break; } } latch.await();//阻塞等待锁 return true; } }catch (InterruptedException e) { e.printStackTrace(); }catch (KeeperException e) { e.printStackTrace(); } return false; } public void unLock(Zookeeper zk) throws InterruptedException, KeeperException { String str = this.currpath; Stat stat = zk.exists(str, false);//查一下节点存在吗? if (stat != null) zk.delete(str,stat.getAversion()); //删除节点 System.out.println(Thread.currentThread().getName() + str); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。