场景描述:

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

  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)控制台效果

最新文章

  1. 【JS】字符串操作
  2. CSS背景图像位置属性background-position百分比详解
  3. docker 服务升级
  4. jdbcTemplate的Dao层封装
  5. 解决在VS2015下用C++开发的DLL在WIN7上无法加载运行
  6. 各种编码UNICODE、UTF-8、ASCII学习笔记
  7. 【BZOJ】1524: [POI2006]Pal
  8. MFC重载关闭按钮
  9. 回车键和button按钮都绑定同一个事件,如何避免按回车的时候button重复点击
  10. URAL 1002 Phone Numbers(KMP+最短路orDP)
  11. lintcode:组成最大的数
  12. Struts2配置细节
  13. 组合 z
  14. 【原】Oracle查询指定表里的触发器
  15. linux 命令(alias , unalias , install ,ar , arch ,uname )
  16. python之pyqt4的简单窗口布局以及信号和槽(上代码)
  17. 关于VB里判断逻辑的说明
  18. window.location.replace和window.location.href区别
  19. 09-部署配置kubedns插件
  20. typescript-koa-postgresql 实现一个简单的rest风格服务器 —— typescript 开发环境配置

热门文章

  1. 测试工程师如何使用 CODING 进行测试管理
  2. MySQL 主从复制问题
  3. MATLAB实例:绘制条形图
  4. sql语句复习(基础-提升-技巧-经典数据开发案例-sql server配置)
  5. Redis入门(三)-Redis的安装及操作key的命令介绍
  6. 一文带你深入浅出Spring 事务原理
  7. Java 添加Word页眉、页脚
  8. 【nodejs原理&amp;源码赏析(4)】深度剖析cluster模块源码与node.js多进程(上)
  9. PostgreSQL 修改表字段常用命令
  10. vue jsx与render的区别及基本使用