场景描述:

  在线程高并发场景下,生成唯一的订单编号,如:

  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分布式锁实战的更多相关文章

  1. Zookeeper 分布式锁 (图解+秒懂+史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

  2. Curator Zookeeper分布式锁

    Curator Zookeeper分布式锁 pom.xml中添加如下配置 <!-- https://mvnrepository.com/artifact/org.apache.curator/c ...

  3. ZooKeeper 分布式锁实现

    1 场景描述 在分布式应用, 往往存在多个进程提供同一服务. 这些进程有可能在相同的机器上, 也有可能分布在不同的机器上. 如果这些进程共享了一些资源, 可能就需要分布式锁来锁定对这些资源的访问. 2 ...

  4. ZooKeeper分布式锁浅谈(一)

    一.概述 清明节的时候写了一篇分布式锁概述,里面介绍了分布式锁实现的几种方式,其实那时候我一直沉迷于使用redis的悲观锁和乐观锁来实现分布式锁,直到一个血案的引发才让我重新认识了redis分布式锁的 ...

  5. [转载] zookeeper 分布式锁服务

    转载自http://www.cnblogs.com/shanyou/archive/2012/09/22/2697818.html 分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那 ...

  6. 跟着大神学zookeeper分布式锁实现-----来自Ruthless

    前几天分享了@Ruthless大神的Redis锁,发现和大家都学习了很多东西.因为分布式锁里面,最好的实现是zookeeper的分布式锁.所以在这里把实现方式和大家分享一下. zookeeper分布式 ...

  7. zookeeper分布式锁

    摘要:分享牛原创,zookeeper使用,zookeeper锁在实际项目开发中还是很常用的,在这里我们介绍一下zookeeper分布式锁的使用,以及我们如何zookeeper分布式锁的原理.zooke ...

  8. 关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁

    首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...

  9. zookeeper 分布式锁原理

    zookeeper 分布式锁原理: 1 大家也许都很熟悉了多个线程或者多个进程间的共享锁的实现方式了,但是在分布式场景中我们会面临多个Server之间的锁的问题,实现的复杂度比较高.利用基于googl ...

随机推荐

  1. 阿里云ECS服务器部署HADOOP集群(五):Pig 安装

    本篇将在阿里云ECS服务器部署HADOOP集群(一):Hadoop完全分布式集群环境搭建的基础上搭建. 1 环境介绍 一台阿里云ECS服务器:master 操作系统:CentOS 7.3 Hadoop ...

  2. element-ui 中Switch的用法

    在element-ui中,如果你想知道Switch是开还是关,使用事件 @change="getchange(value2)" 它会输出true或者false.true代表的是开, ...

  3. Bandizip解压压缩软件

    上次重装系统以后,特别注意安装软件,在这里提一些比较好的 解压软件:Bandizip 这个是一个免费轻量级的软件,压缩解压速度快,没什么广告,推荐大家在官方下载 Bandizip下载网址 点击下载安装 ...

  4. 【使用篇二】SpringBoot使用Druid作为数据源(19)

    Druid是一个关系型数据库连接池,它是阿里巴巴的一个开源项目.Druid支持所有JDBC兼容数据库,包括了Oracle.MySQL.PostgreSQL.SQL Server.H2等.Druid在监 ...

  5. oracle 中 insert select 和 select insert 配合使用

    Insert Into select 与 Select Into 哪个更快? 在平常数据库操作的时候,我们有时候会遇到表之间数据复制的情况,可能会用到INSERT INTO SELECT 或者 SEL ...

  6. java对象引用测试

    代码 java中初始化一个实例,这个实例对应的只是对象的一个地址,并不是对象本身.将这个实例赋值给别的实例时,新实例也是指向对象的地址,两个实例实际指向的是同一个实例.对新实例赋值,老实例也会同时改变 ...

  7. HashMap如何在Java中工作?

    通过优锐课学习笔记分享,我们可以看到HashMap问题在工作面试中很常见. 这也是HashMaps在Java内部如何工作的一些深入说明,分享给大家参考学习. HashMap在内部如何工作已成为几乎所有 ...

  8. Java基础(七)

    左连接,右连接,内连接,全连接的区别 左连接:返回左表所有行,右表没有匹配行则返回null 右连接:返回右表所有行,左表没有匹配行则返回null 内连接:返回左右表共有行 全连接:返回左右表所有行,无 ...

  9. Scrapy框架-爬虫程序相关属性和方法汇总

    一.爬虫项目类相关属性 name:爬虫任务的名称 allowed_domains:允许访问的网站 start_urls: 如果没有指定url,就从该列表中读取url来生成第一个请求 custom_se ...

  10. Hacking/Penetrating tester bookmark collection

    Blogs http://carnal0wnage.blogspot.com/ http://www.mcgrewsecurity.com/ http://www.gnucitizen.org/blo ...