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 implements Watcher {
private ZooKeeper zk;
//当前锁
private String currentLock;
//资源名称
private String lockName;
//锁根节点
private String ROOT_LOCK = "/root_lock";
//锁的各个资源根节点
private String tmpRootLock;
//由于zookeeper监听节点状态会立即返回,所以需要使用CountDownLatch(也可使用信号量等其他机制)
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);//****zk临时节点下不能创建临时顺序节点
} catch (IOException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} private void createZNode(String node, CreateMode mode) throws KeeperException, InterruptedException {
//获取根节点状态
Stat stat = zk.exists(node, false);
//如果根节点不存在,则创建根节点,根节点类型为永久节点
if (stat == null) {
zk.create(node, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, mode);
}
} public void lock() {
try {
//在根节点下创建临时顺序节点,返回值为创建的节点路径
currentLock = zk.create(tmpRootLock + "/" + lockName, new byte[0],
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
//获取根节点下的所有临时顺序节点,不设置监视器
List<String> children = zk.getChildren(tmpRootLock, false);
//对根节点下的所有临时顺序节点进行从小到大排序
children.sort(null);
//判断当前节点是否为最小节点,如果是则获取锁,若不是,则找到自己的前一个节点,监听其存在状态
int curIndex = children.indexOf(currentLock.substring(currentLock.lastIndexOf("/") + 1));
if (curIndex != 0) {
//获取当前节点前一个节点的路径
String prev = children.get(curIndex - 1);
//监听当前节点的前一个节点的状态,null则节点不存在
Stat stat = zk.exists(tmpRootLock + "/" + prev, true);
//此处再次判断该节点是否存在
if (stat != null) {
latch = new CountDownLatch(1);
//进入等待锁状态
latch.await();
latch = null;
}
}
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} //释放锁
public void unlock() {
try {
//删除创建的节点
zk.delete(currentLock, -1);
List<String> children = zk.getChildren(tmpRootLock, false);
if (children.size() == 0) {
zk.delete(tmpRootLock, -1);
//关闭zookeeper连接
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 = "";
}
}

基于zk“临时顺序节点“的分布式锁的更多相关文章

  1. Zookeeper--0300--java操作Zookeeper,临时节点实现分布式锁原理

    删除Zookeeper的java客户端有  : 1,Zookeeper官方提供的原生API, 2,zkClient,在原生api上进行扩展的开源java客户端 3, 一.Zookeeper原生API ...

  2. 【spring boot】【redis】spring boot基于redis的LUA脚本 实现分布式锁

    spring boot基于redis的LUA脚本 实现分布式锁[都是基于redis单点下] 一.spring boot 1.5.X 基于redis 的 lua脚本实现分布式锁 1.pom.xml &l ...

  3. 【连载】redis库存操作,分布式锁的四种实现方式[四]--基于Redis lua脚本机制实现分布式锁

    一.redis lua介绍 Redis 提供了非常丰富的指令集,但是用户依然不满足,希望可以自定义扩充若干指令来完成一些特定领域的问题.Redis 为这样的用户场景提供了 lua 脚本支持,用户可以向 ...

  4. 基于redis集群实现的分布式锁,可用于秒杀商品的库存数量管理,有測试代码(何志雄)

    转载请标明出处. 在分布式系统中,常常会出现须要竞争同一资源的情况,本代码基于redis3.0.1+jedis2.7.1实现了分布式锁. redis集群的搭建,请见我的另外一篇文章:<>& ...

  5. 基于redis集群实现的分布式锁,可用于秒杀,定时器。

    在分布式系统中,经常会出现需要竞争同一资源的情况,使用redis可以实现分布式锁. 前提:redis集群已经整合项目,并且可以直接注入JedisCluster使用: @Autowired privat ...

  6. java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购

    此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...

  7. zookeeper(4)--zookeeper分布式锁原理

    目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency).可用性( ...

  8. ZooKeeper的分布式锁实现

    分布式锁一般有三种实现方式: 1. 数据库乐观锁: 2. 基于Redis的分布式锁: 3. 基于ZooKeeper的分布式锁. 本篇博客将介绍第三种方式,基于Zookeeper实现分布式锁.虽然网上已 ...

  9. zookeeper分布式锁原理

    一.分布式锁介绍分布式锁主要用于在分布式环境中保护跨进程.跨主机.跨网络的共享资源实现互斥访问,以达到保证数据的一致性. 二.架构介绍在介绍使用Zookeeper实现分布式锁之前,首先看当前的系统架构 ...

随机推荐

  1. 查看表空间使用率及shrink 表空间

    首先,可以通过下面的sql statement来查看表空间的使用情况.注意,该语句是在10g下测试过. SELECT FREE.TABLESPACE_NAME, FREE.FREE_SPACE/TOT ...

  2. golang中select case 的用途到底是啥

    https://nanxiao.gitbooks.io/golang-101-hacks/content/posts/select-operation.html ------------------- ...

  3. CocoaPods 的安装和使用介绍

    CocoaPods 的安装和使用介绍 安装 安装方式异常简单 , Mac 下都自带 ruby,使用 ruby 的 gem 命令即可下载安装: 1 2 $ sudo gem install cocoap ...

  4. HDU 4249 A Famous Equation(数位DP)

    题目链接:点击打开链接 思路:用d[i][a][b][c][is]表示当前到了第i位, 三个数的i位各自是a,b,c, 是否有进位 , 的方法数. 细节參见代码: #include<cstdio ...

  5. ZOJ 3888 Twelves Monkeys (预处理+优先队列)

    题目链接:ZOJ 3888 Twelves Monkeys 题意:题目描写叙述起来比較绕,直接讲案例 9 3 3 9 1 6 1 4 1 6 7 2 输入n,m,q.n限制了你询问的年份,m台时光机, ...

  6. jquery 实现可编辑div

    html大致例如以下: <ol id="ol_group" class="list-group list_of_items"> <li cla ...

  7. intellij idea 写 Helloworld

    http://www.jetbrains.com/idea/webhelp/creating-and-running-your-first-java-application.html Creating ...

  8. 金典 SQL笔记 SQL语句汇总

    SELECT * FROM (SELECT ROW_NUMBER() OVER ( ORDER BY id) AS rowN,FNumber, FName,FSalary ,Fage FROM dbo ...

  9. MBEEWALK - Bee Walk

    A bee larva living in a hexagonal cell of a large honey comb decides to creep for a walk. In each “s ...

  10. E: Unable to lock the administration directory (/var/lib/dpkg/)

    如何修复 Ubuntu 中的“Unable to lock the administration directory (/var/lib/dpkg/)” 在 Ubuntu 或者它的衍生版如 Linux ...