zk实现分布式锁
public interface lock {
void getLock();
void unLock();
}
public abstract class ZkAbstractLock implements lock{
//zk连接地址
private static final String CONNECTSTRING = "127.0.0.1:2181";
//创建zk连接
protected ZkClient zkClient = new ZkClient(CONNECTSTRING);
//PATH
protected static final String PATH = "/lock";
public abstract boolean tryLock();
public abstract void waitLock();
public void getLock() {
if (tryLock()) {
System.out.println("###成功获取锁###");
} else {
waitLock();
getLock();
}
}
public void unLock() {
if(zkClient!=null){
zkClient.close();
System.out.println("###释放所资源###");
}
}
}
**
* @Auther:
* @Date: 星期一:2019/4/29 15
* @Description: zk基于异常的阻塞式锁
*/
public class ZKExceptionLock extends ZkAbstractLock {
private String lockPath;
private CountDownLatch countDownLatch = new CountDownLatch(1); public ZKExceptionLock(String lockPath) {
this.lockPath = PATH + "/" + lockPath;
}
public boolean tryLock() {
try {
zkClient.createEphemeral(lockPath);
return true;
}catch (Exception e){
return false;
}
} public void waitLock() {
zkClient.subscribeDataChanges(lockPath, new IZkDataListener() {
public void handleDataChange(String s, Object o) throws Exception {
System.out.println("---handleDataChange---");
} public void handleDataDeleted(String s) throws Exception {
countDownLatch.countDown();
}
}); try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void unLock(){
zkClient.delete(lockPath);
}
}
/**
* @Auther:
* @Date: 星期一:2019/4/29 12
* @Description: zk基于监听的阻塞式锁
*/
public class ZkListenerLock extends ZkAbstractLock {
private static final CountDownLatch LATCH = new CountDownLatch(1);
private String lockPath;
private String currentPath;
private String beforePath; public ZkListenerLock(String lockPath) {
if (!zkClient.exists(PATH)) {
zkClient.createPersistent(PATH);
}
this.lockPath = PATH+"/"+lockPath;
if (!zkClient.exists(this.lockPath)) {
System.out.println("-----------");
zkClient.createPersistent(this.lockPath);
}
} public boolean tryLock() {
if (null == currentPath || currentPath.length()<=0 ) {
currentPath = zkClient.createEphemeralSequential(lockPath + "/", "lock");
}
List<String> children = zkClient.getChildren(lockPath);//0000000007
Collections.sort(children);
System.out.println(children);
if (currentPath.equals(lockPath + "/"+children.get(0))) {
return true;
}
String key = currentPath.substring(lockPath.length() + 1);
int location = Collections.binarySearch(children, key);
this.beforePath = lockPath + "/" + children.get(location - 1);
return false;
} public void waitLock() {
IZkDataListener listener = new IZkDataListener() {
public void handleDataChange(String s, Object o) throws Exception {
System.out.println("--handleDataChange--");
}
public void handleDataDeleted(String s) throws Exception {
LATCH.countDown();
}
};
zkClient.subscribeDataChanges(this.beforePath,listener);
if (!zkClient.exists(this.beforePath)) {
return;
}
try {
LATCH.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
zkClient.unsubscribeDataChanges(this.beforePath,listener);
} @Override
public void unLock() {
zkClient.delete(currentPath);
}
}
public class TestLock {
public static void main(String[] args) {
int i = 0;
while (i < 10) {
People people = new People();
people.start();
i++;
}
System.out.println(People.totalMoney);
}
static class People extends Thread{
private ZkListenerLock lock = new ZkListenerLock("order");
private ZKExceptionLock lock2 = new ZKExceptionLock("order2");
public static int totalMoney = 50;
public void run(){
try {
//获取锁资源
lock2.getLock();
totalMoney--;
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放锁资源
lock2.unLock();
}
}
}
}
基于监听的zk锁:L值就是建立有序节点后返回的序列号

基于异常的zk锁:

pom.xml:
<dependencies>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
</dependencies>
zk实现分布式锁的更多相关文章
- zookeeper笔记之基于zk实现分布式锁
一.分布式锁概述 Java中基于AQS框架提供了一系列的锁,但是当需要在集群中的多台机器上互斥执行一段代码或使用资源时Java提供的这种单机锁就没了用武之地,此时需要使用分布式锁协调它们.分布式锁有很 ...
- 基于ZK的分布式锁实现
import java.util.concurrent.TimeUnit; import org.apache.curator.framework.CuratorFramework; import o ...
- 2020-06-18:ZK的分布式锁怎么实现?
福哥答案2020-06-18: Zk分布式锁有两种实现方式一种比较简单,应对并发量不是很大的情况.获得锁:创建一个临时节点,比如/lock,如果成功获得锁,如果失败没获得锁,返回false释放锁:删除 ...
- 【zookeeper】Apache curator的使用及zk分布式锁实现
上篇,本篇主要讲Apache开源的curator的使用,有了curator,利用Java对zookeeper的操作变得极度便捷. 其实在学之前我也有个疑虑,我为啥要学curator,撇开涨薪这些外在的 ...
- 分布式锁-基于ZK和Redis实现
一.基于zookeeper实现分布式锁 1.1 Zookeeper的常用接口 package register; import java.util.List; import java.util.con ...
- 面试必问:分布式锁实现之zk(Zookeeper)
点赞再看,养成习惯,微信搜索[三太子敖丙]关注这个互联网苟且偷生的工具人. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的 ...
- 【分布式锁的演化】终章!手撸ZK分布式锁!
前言 这应该是分布式锁演化的最后一个章节了,相信很多小伙伴们看完这个章节之后在应对高并发的情况下,如何保证线程安全心里肯定也会有谱了.在实际的项目中也可以参考一下老猫的github上的例子,当然代码没 ...
- 一般实现分布式锁都有哪些方式?使用redis如何设计分布式锁?使用zk来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高?
#(1)redis分布式锁 官方叫做RedLock算法,是redis官方支持的分布式锁算法. 这个分布式锁有3个重要的考量点,互斥(只能有一个客户端获取锁),不能死锁,容错(大部分redis节点创建了 ...
- zk系列三:zookeeper实战之分布式锁实现
一.分布式锁的通用实现思路 分布式锁的概念以及常规解决方案可以参考之前的博客:聊聊分布式锁的解决方案:今天我们先分析下分布式锁的实现思路: 首先,需要保证唯一性,即某一时点只能有一个线程访问某一资源: ...
随机推荐
- 全国高校绿色计算大赛 预赛第二阶段(Python)第1关:统计分数的麻烦
挑战任务 “绿盟杯”比赛过后,赛事承办方的各位工作人员们就开始分头统计各个参赛队伍和同学的成绩了.赛事规模很大,有10000个队伍参加.经过工作人员认真负责的统计,本来已经统计好了这一万个队伍的分数和 ...
- 贪吃蛇 Java实现(一)
贪吃蛇 Java实现 1.面向对象思想 1.创建antition包它是包含sanke Ground Food类 2.创建Controller包controller类 3.创建Game包有game类 ...
- vue 添加子路由,并对路由重定向
// 用户信息首页 { path: '/user/index', name: 'userIndex', component: userIndex, redirect: '/user/index/sho ...
- tomcat配置的环境变量catalina.home和catalina.base 区别
本篇文章原创地址为:http://blog.csdn.net/you23hai45/article/details/27726147 这两个属性仅在你需要安装多个Tomcat实例而不想安装多个软件备份 ...
- ClickHouse高性能数据库
ClickHouse之简单性能测试 前面的文章ClickHouse之初步认识已经简单的介绍了ClickHouse,接下来进行简单的性能测试.测试数据来源于美国民用航班的数据,从1987年到2017 ...
- H5笔记周记
9.4 一.介绍浏览器 1.title 主题,题目 2.url 网址 3.body 网站的内容 4.html 语言,超文本标记语言 二.文件介绍 三.标签的结构 (一些快捷键:Ctrl+s 保存 ...
- Oracle_SQL(2) 分组与聚合函数
一.聚合函数1.定义:对表或视图的查询时,针对多行记录只返回一个值的函数.2.用途:用于select语句,HAVING条件二.5种聚合函数1.SUM(n) 对列求和 select sum(sal) f ...
- 在浏览器中运行java applet
最近在看java applet,在eclipse中可以正常运行,于是想试试在浏览器中运行.但途中遇到很多问题,网上很多解答也不全面,于是想把自己的解决过程记录下来. [1]首先,编写的applet程序 ...
- mybatis进阶--mapper输入映射和输出映射
我们知道,mapper.xml是我们配置操作数据库的sql语句的地方.其中每个sql语句对应着一个方法,每个方法都有自己的输入输出参数类型.那么这些类型都是怎么配置的呢?今天我们来一起学习下. 输入映 ...
- 发送邮件--MFMailComposeViewController
只能在真机使用. 模拟器没有E-mail发送功能.无法调用 #import "EmailViewController.h" #import <UIKit/UIKit.h> ...