场景描述:

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

  2017-10-14-20-52-33-01

  年-月-日-时-分-秒-序号

(1)Lock锁接口

  1. package com.zookeeper.day02;
  2.  
  3. /**
  4. * 锁接口
  5. */
  6. public interface Lock {
  7. //获取锁
  8. public void getLock();
  9.  
  10. //释放锁
  11. public void unLock();
  12. }

(2)OrderNumber订单产生的类

  1. package com.zookeeper.day02;
  2.  
  3. import java.text.SimpleDateFormat;
  4. import java.util.Date;
  5.  
  6. /**
  7. * 产生订单的类
  8. */
  9. public class OrderNumber {
  10. private static Integer number=0;
  11. //生成订单号
  12. public String getNumber(){
  13. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
  14. ++number;
  15. return simpleDateFormat.format(new Date())+"\t"+number;
  16. }
  17. }

(3)ZookeeperLock

  1. package com.zookeeper.day02;
  2.  
  3. import org.I0Itec.zkclient.ZkClient;
  4.  
  5. public abstract class ZookeeperLock implements Lock{
  6. /**
  7. * 创建zkClient连接对象
  8. */
  9. private static final String ZK_ADDRESS="0.0.0.0:2181";
  10.  
  11. protected ZkClient zkClient=new ZkClient(ZK_ADDRESS);
  12.  
  13. /**
  14. * 每一个进程在创建节点时,实际上就是获得了一把锁,如果在获取锁是发现返回值为true,代表当前没有锁,我可以使用,如果返回值为false,代表锁正在被占用,那么我只能等待
  15. * @return
  16. */
  17. @Override
  18. public void getLock() {
  19. //获取一把锁
  20. if(tryLock()){
  21. System.out.println("获取到锁资源");
  22. }else{
  23. //当返回值为false时,代表当前锁正在被使用,等待
  24. waitLock();
  25. //等待之后我得再次获取,我不再次获取我怎么能得到锁资源
  26. getLock();
  27. }
  28.  
  29. }
  30.  
  31. /**
  32. * 释放锁,zk关闭
  33. */
  34. @Override
  35. public void unLock() {
  36. if(zkClient!=null){
  37. zkClient.close();
  38. }
  39. }
  40.  
  41. //获取锁资源
  42. public abstract boolean tryLock();
  43.  
  44. //等待
  45. public abstract void waitLock();
  46. }

(4)ZkLockImpl

  1. package com.zookeeper.day02;
  2.  
  3. import org.I0Itec.zkclient.IZkChildListener;
  4. import org.I0Itec.zkclient.IZkDataListener;
  5.  
  6. import java.util.concurrent.CountDownLatch;
  7.  
  8. public class ZkLockImpl extends ZookeeperLock{
  9.  
  10. private CountDownLatch countDownLatch=null;
  11.  
  12. @Override
  13. public boolean tryLock() {
  14. try {
  15. //创建临时节点
  16. zkClient.createEphemeral("/zkTemp");
  17. return true;
  18. }catch (Exception ex){
  19. return false;
  20. }
  21. }
  22.  
  23. @Override
  24. public void waitLock() {
  25. //监听节点是否是删除了
  26. IZkDataListener iZkDataListener=new IZkDataListener() {
  27. @Override
  28. public void handleDataChange(String s, Object o) throws Exception {
  29.  
  30. }
  31.  
  32. @Override
  33. public void handleDataDeleted(String s) throws Exception {
  34. if(countDownLatch!=null){
  35. //释放掉
  36. countDownLatch.countDown();
  37. }
  38. }
  39. };
  40.  
  41. //如果已经存在zkTemp节点,就等待
  42. if(zkClient.exists("/zkTemp")){
  43. countDownLatch=new CountDownLatch(1);
  44. System.out.println("订单号重复,请等待=================================");
  45. try {
  46. countDownLatch.await();
  47. } catch (InterruptedException e) {
  48. e.printStackTrace();
  49. }
  50. }
  51. }
  52. }

(5)OrderService

  1. package com.zookeeper.day02;
  2.  
  3. /**
  4. * 订单业务处理类
  5. */
  6. public class OrderService implements Runnable{
  7. private static OrderNumber orderNumber=new OrderNumber();
  8. private Lock lock=new ZkLockImpl();
  9.  
  10. //生成订单
  11. public void getOrderNumber(){
  12. //同步代码块:多个线程访问同一个资源时
  13. /*synchronized (orderNumber){
  14.  
  15. }*/
  16.  
  17. //获取锁
  18. lock.getLock();
  19. System.out.println("当前生成的订单编号为:"+orderNumber.getNumber());
  20. //释放锁
  21. lock.unLock();
  22.  
  23. }
  24.  
  25. @Override
  26. public void run() {
  27. getOrderNumber();
  28. }
  29.  
  30. public static void main(String[] args) {
  31. //生成100个线程
  32. for(int i=1;i<=100;i++){
  33. new Thread(new OrderService()).start();
  34. }
  35. }
  36. }

(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. iOS多线程知识梳理

    iOS多线程知识梳理 线程进程基础概念 进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 线程 1个进程要想执行任务,必须得有线程(每1个 ...

  2. Python 基础语法-str

    字符串常见操作 find:检测str是否包含在 mystr 中,如果是返回开始的索引值,否则返回 -1 mystr.index(str, start=0, end=len(mystr)) count: ...

  3. Hazelcast介绍

    Hazelcast介绍 什么时侯需要用例 内存中分布式计算 场景分布式消息 特性 全景 Distributed Maps 一个结点中分区 Hazelcast中的分片也称为分区,Hazelcast默认2 ...

  4. Python selenium登录163邮箱示例

    思路:使用python自带的unittest单元测试框架测试163邮箱登录成功的case import unittestfrom selenium import webdriverimport tim ...

  5. 外部调用Tomcat启动脚本后日志中文显示乱码问题的解决

    外部sh脚本如下 #!/bin/bash while read LINE do echo "Hello $LINE!" case $LINE in all) tail -f -n2 ...

  6. 朝花夕拾《精通CSS》一、HTML & CSS 的基础

    一.背景 翻出我4年前看的<精通CSS>一书,可惜当初没有整理读书笔记的习惯,最近又很少写前端,遂很多东西.知识点遗忘了,恰且现在 css 也有些变化和进步,遂一起打包整理,输出成几篇 b ...

  7. 01-linux介绍

    一.Linux简介 Linux内核最初只是由芬兰人林纳斯.托瓦兹在大学时出于爱好写出来的,是一套免费使用和自由传播的类Unix操作系统,是基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU ...

  8. thinkphp5.0学习笔记

    2019-11-11学习笔记 安装TP5.0 a)源代码包下载 在thinkphp官网下载(www.thinkphp.cn)下载 完整版本的TP5.0 b) composer 安装 切换到网站的根目录 ...

  9. 我眼中的 RPC

    目录 什么是 RPC ? 什么情况下使用 RPC ? RPC 框架原理 RPC 调用过程 RPC 优点 RPC 缺点 PHP RPC 有哪些? 小结 推荐阅读 什么是 RPC ? RPC 是一种框架或 ...

  10. NFS客户端挂载及永久生效

    1.NFS客户端挂载的命令格式: 挂载命令 挂载的格式类型 NFS服务器提供的共享目录 NFS客户端要挂载的目录mount -t nfs 服务器IP:/共享目录 /本地的挂载点(必须存在) 重启失效 ...