定义一个公共资源订单生成类:

package com.itmayiedu.lock;

import java.text.SimpleDateFormat;
import java.util.Date; //生成订单号规则
public class OrderNumGenerator {
private static int count = 0; //生成订单号规则方法 public String orderNumber() {
SimpleDateFormat simpt = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
return simpt.format(new Date()) + "-" + ++count;
} }

  定义一个模拟多线程接口:

package com.itmayiedu.lock;

//订单服务
public class OrderService implements Runnable {
private OrderNumGenerator orderNumGenerator = new OrderNumGenerator();
private static Object oj = new Object();
private Lock lock=new ZookeeperDistrbuteLock(); public void run() {
getNumber();
} public void getNumber() {
// synchronized (oj) {
lock.getLock();
String number = orderNumGenerator.orderNumber();
System.out.println(Thread.currentThread().getName() + ",生成订单号:" + number);
lock.unLock(); } public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(new OrderService()).start();
}
} }

定义锁接口:

package com.itmayiedu.lock;

public interface Lock {
//获取到锁的资源
public void getLock();
// 释放锁
public void unLock();
}

抽象类:

package com.itmayiedu.lock;

import org.I0Itec.zkclient.ZkClient;

//将重复的代码,具体业务逻辑有子类去实现.
public abstract class ZookeeperAbstractLock implements Lock {
private static final String CONNECT_ADDRES = "192.168.110.159:2181,192.168.110.160:2181,192.168.110.162:2181";
protected ZkClient zkClient = new ZkClient(CONNECT_ADDRES);
protected static final String PATH = "/lock"; public void getLock() {
// tryLock() 创建zk临时节点 如果创建成功返回true 否则返回false
if (tryLock()) {
System.out.println("获取到锁的资源 get lock");
} else {
// 等待
waitLock();
// 重写获取锁的资源
getLock();
} } protected abstract boolean tryLock(); protected abstract void waitLock(); // 释放锁
public void unLock() {
if (zkClient != null) {
zkClient.close();
}
System.out.println("释放锁的资源.."); } }

实现类:

package com.itmayiedu.lock;

import java.util.concurrent.CountDownLatch;

import org.I0Itec.zkclient.IZkDataListener;

public class ZookeeperDistrbuteLock extends ZookeeperAbstractLock {
private CountDownLatch countDownLatch = null; @Override
protected boolean tryLock() {
try {
zkClient.createEphemeral(PATH);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} @Override
protected void waitLock() {
IZkDataListener zkDataListener = new IZkDataListener() {
// 节点被删除的时候 事件通知
public void handleDataDeleted(String path) throws Exception {
// 唤醒被等待的线程
if (countDownLatch != null) {
countDownLatch.countDown();
System.out.println("删除节点.....");
}
} public void handleDataChange(String path, Object data) throws Exception { }
};
// 注册到zkclient进行监听
zkClient.subscribeDataChanges(PATH, zkDataListener);
if (zkClient.exists(PATH)) {
countDownLatch = new CountDownLatch(1);
try {
countDownLatch.await();
} catch (Exception e) {
// TODO: handle exception
}
}
// 删除监听
zkClient.unsubscribeDataChanges(PATH, zkDataListener);
} }

Zookeeper分布式锁解决方案具体代码的更多相关文章

  1. 分布式缓存重建并发冲突和zookeeper分布式锁解决方案

    如果缓存服务在本地的ehcache中都读取不到数据. 这个时候就意味着,需要重新到源头的服务中去拉去数据,拉取到数据之后,赶紧先给nginx的请求返回,同时将数据写入ehcache和redis中 分布 ...

  2. ZooKeeper分布式锁简单实践

    ZooKeeper分布式锁简单实践 在分布式解决方案中,Zookeeper是一个分布式协调工具.当多个JVM客户端,同时在ZooKeeper上创建相同的一个临时节点,因为临时节点路径是保证唯一,只要谁 ...

  3. 死磕 java同步系列之zookeeper分布式锁

    问题 (1)zookeeper如何实现分布式锁? (2)zookeeper分布式锁有哪些优点? (3)zookeeper分布式锁有哪些缺点? 简介 zooKeeper是一个分布式的,开放源码的分布式应 ...

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

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

  5. Curator Zookeeper分布式锁

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

  6. ZooKeeper 分布式锁实现

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

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

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

  8. zookeeper分布式锁

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

  9. zookeeper 分布式锁原理

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

随机推荐

  1. C# ArcgisEngine开发中,对一个图层进行过滤,只显示符合条件的要素

    转自原文 C# ArcgisEngine开发中,对一个图层进行过滤,只显示符合条件的要素 有时候,我们要对图层上的地物进行有选择性的显示,以此来满足实际的功能要求. 按下面介绍的方法可轻松实现图层属性 ...

  2. POJ 2030

    简单DP题. 可以用运算符重载来写,简单一些. #include <iostream> #include <cstdio> #include <cstring> # ...

  3. 使用 F# 列表

    使用 F# 列表 在 C# 中使用 F# 的列表,是全然可能的,可是,我建议不要用,由于,仅仅要再做一点,就会使事情在 C# 看来更加自然.比如,把列表转换成数组非常easy.用List.toArra ...

  4. Tomcat报错合集

    1.java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start c ...

  5. hdu 2883 kebab(时间区间压缩 &amp;&amp; dinic)

    kebab Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  6. 在ubuntu中安装与配置zsh与oh-my-zsh

    先补充点东西 1.ubuntu中默认安装了那些shell jiang@Linux:~$ cat /etc/shells # /etc/shells: valid login shells/bin/sh ...

  7. [Javascript] 40个轻量级JavaScript脚本库

    诸如jQuery, MooTools, Prototype, Dojo和YUI等JavaScript脚本库,大家都已经很熟悉.但这些脚本库有利也有弊--比如说JavaScript文件过大的问题.有时你 ...

  8. codeforces 712A. Memory and Crow

    2019-05-18 08:48:27 加油,加油,坚持!!! 这道题我没有想出公式推导,只是按照模拟题来做,第5个样例超时 样例超时,方法错误 https://www.cnblogs.com/ECJ ...

  9. table合并单元格 colspan(跨列)和rowspan(跨行)

    colspan和rowspan这两个属性用于创建特殊的表格. colspan是“column span(跨列)”的缩写.colspan属性用在td标签中,用来指定单元格横向跨越的列数: 在浏览器中将显 ...

  10. Mysql库的操作

    一.系统数据库 执行如下命令,查看系统库 show databases; information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息 ...