Zookeeper分布式锁实战
场景描述:
在线程高并发场景下,生成唯一的订单编号,如:
2017-10-14-20-52-33-01
年-月-日-时-分-秒-序号

(1)Lock锁接口
package com.zookeeper.day02; /**
* 锁接口
*/
public interface Lock {
//获取锁
public void getLock(); //释放锁
public void unLock();
}
(2)OrderNumber订单产生的类
package com.zookeeper.day02; import java.text.SimpleDateFormat;
import java.util.Date; /**
* 产生订单的类
*/
public class OrderNumber {
private static Integer number=0;
//生成订单号
public String getNumber(){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
++number;
return simpleDateFormat.format(new Date())+"\t"+number;
}
}
(3)ZookeeperLock
package com.zookeeper.day02;
import org.I0Itec.zkclient.ZkClient;
public abstract class ZookeeperLock implements Lock{
/**
* 创建zkClient连接对象
*/
private static final String ZK_ADDRESS="0.0.0.0:2181";
protected ZkClient zkClient=new ZkClient(ZK_ADDRESS);
/**
* 每一个进程在创建节点时,实际上就是获得了一把锁,如果在获取锁是发现返回值为true,代表当前没有锁,我可以使用,如果返回值为false,代表锁正在被占用,那么我只能等待
* @return
*/
@Override
public void getLock() {
//获取一把锁
if(tryLock()){
System.out.println("获取到锁资源");
}else{
//当返回值为false时,代表当前锁正在被使用,等待
waitLock();
//等待之后我得再次获取,我不再次获取我怎么能得到锁资源
getLock();
}
}
/**
* 释放锁,zk关闭
*/
@Override
public void unLock() {
if(zkClient!=null){
zkClient.close();
}
}
//获取锁资源
public abstract boolean tryLock();
//等待
public abstract void waitLock();
}
(4)ZkLockImpl
package com.zookeeper.day02; import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener; import java.util.concurrent.CountDownLatch; public class ZkLockImpl extends ZookeeperLock{ private CountDownLatch countDownLatch=null; @Override
public boolean tryLock() {
try {
//创建临时节点
zkClient.createEphemeral("/zkTemp");
return true;
}catch (Exception ex){
return false;
}
} @Override
public void waitLock() {
//监听节点是否是删除了
IZkDataListener iZkDataListener=new IZkDataListener() {
@Override
public void handleDataChange(String s, Object o) throws Exception { } @Override
public void handleDataDeleted(String s) throws Exception {
if(countDownLatch!=null){
//释放掉
countDownLatch.countDown();
}
}
}; //如果已经存在zkTemp节点,就等待
if(zkClient.exists("/zkTemp")){
countDownLatch=new CountDownLatch(1);
System.out.println("订单号重复,请等待=================================");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
(5)OrderService
package com.zookeeper.day02; /**
* 订单业务处理类
*/
public class OrderService implements Runnable{
private static OrderNumber orderNumber=new OrderNumber();
private Lock lock=new ZkLockImpl(); //生成订单
public void getOrderNumber(){
//同步代码块:多个线程访问同一个资源时
/*synchronized (orderNumber){ }*/ //获取锁
lock.getLock();
System.out.println("当前生成的订单编号为:"+orderNumber.getNumber());
//释放锁
lock.unLock(); } @Override
public void run() {
getOrderNumber();
} public static void main(String[] args) {
//生成100个线程
for(int i=1;i<=100;i++){
new Thread(new OrderService()).start();
}
}
}
(6)控制台效果

Zookeeper分布式锁实战的更多相关文章
- Zookeeper 分布式锁 (图解+秒懂+史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
- Curator Zookeeper分布式锁
Curator Zookeeper分布式锁 pom.xml中添加如下配置 <!-- https://mvnrepository.com/artifact/org.apache.curator/c ...
- ZooKeeper 分布式锁实现
1 场景描述 在分布式应用, 往往存在多个进程提供同一服务. 这些进程有可能在相同的机器上, 也有可能分布在不同的机器上. 如果这些进程共享了一些资源, 可能就需要分布式锁来锁定对这些资源的访问. 2 ...
- ZooKeeper分布式锁浅谈(一)
一.概述 清明节的时候写了一篇分布式锁概述,里面介绍了分布式锁实现的几种方式,其实那时候我一直沉迷于使用redis的悲观锁和乐观锁来实现分布式锁,直到一个血案的引发才让我重新认识了redis分布式锁的 ...
- [转载] zookeeper 分布式锁服务
转载自http://www.cnblogs.com/shanyou/archive/2012/09/22/2697818.html 分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那 ...
- 跟着大神学zookeeper分布式锁实现-----来自Ruthless
前几天分享了@Ruthless大神的Redis锁,发现和大家都学习了很多东西.因为分布式锁里面,最好的实现是zookeeper的分布式锁.所以在这里把实现方式和大家分享一下. zookeeper分布式 ...
- zookeeper分布式锁
摘要:分享牛原创,zookeeper使用,zookeeper锁在实际项目开发中还是很常用的,在这里我们介绍一下zookeeper分布式锁的使用,以及我们如何zookeeper分布式锁的原理.zooke ...
- 关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁
首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...
- zookeeper 分布式锁原理
zookeeper 分布式锁原理: 1 大家也许都很熟悉了多个线程或者多个进程间的共享锁的实现方式了,但是在分布式场景中我们会面临多个Server之间的锁的问题,实现的复杂度比较高.利用基于googl ...
随机推荐
- Android 程序分析环境搭建-动态分析环境搭建
静态查看过app 的代码,但是有些app 非常复杂,页面好多,你根本找不到从何处下手.还有app 通过静态分析,发现有被加固(后续会讲如何砸壳),根本找不到,还有即便你搜索app界面上的文字,你也搜索 ...
- SpringBoot项目里,让TKmybatis支持可以手写sql的Mapper.xml文件
SpringBoot项目通常配合TKMybatis或MyBatis-Plus来做数据的持久化. 对于单表的增删改查,TKMybatis优雅简洁,无需像传统mybatis那样在mapper.xml文件里 ...
- python 基础学习笔记(4)--字典 和 集合
**字典:** - [ ] 列表可以存储大量的数据,但是如果数据量大的话,他的查询速度比较慢,因为列表只能顺序存储,数据与数据之间的关联性不强.所以便有了字典(dict)这种容器的数据类型,它是以{} ...
- 12C-使用跨平台增量备份减少可移动表空间的停机时间 (Doc ID 2005729.1)
12C - Reduce Transportable Tablespace Downtime using Cross Platform Incremental Backup (Doc ID 20057 ...
- 【ES6学习笔记之】Object.assign()
基本用法 Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target). const target = { a: 1 }; const sou ...
- Java实现网络聊天中使用的socket API与Linux socket API之间的关系
尝试着用Java编写一个网络聊天程序,发现总不如网上写的好,所以就直接引用了网上大神的优秀代码.代码如下: package project1; import java.awt.*; import ja ...
- 分享Java程序员50多道热门的多线程和并发面试题(答案解析)
下面是Java程序员相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器 ...
- c++实现通讯录管理系统(控制台版)
c++实现通讯录管理系统(控制台版) 此项目适合c++初学者,针对c++基础知识,涉及到变量.结构体定义使用.数组定义使用.指针定义使用等. 运行之后的结果如下: 代码: #include <i ...
- IDEA 护眼色设置
首先做一些简单的记录,护眼色 等等的设置很久以前机器上已经设置过了,今天偶尔要在其他机器上重新做一些设置反而忘记了很多步骤, 设置后的HTML页面如下图所示: 默认情况下,当只是设置General通用 ...
- 一分钟了解Docker
一.Docker概述 Docker和虚拟机一样,都拥有环境隔离的能力,但它比虚拟机更加轻量级,可以使资源更大化地得到应用. Docker用途:简单配置.代码流水线管理.开发效率.应用隔离.服务器整合. ...