zookeeper实现商品秒杀抢购
package com.test; import java.io.IOException;
import java.util.List;
import java.util.concurrent.CyclicBarrier; import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat; public class Main { public static void main(String[] args) throws IOException, KeeperException, InterruptedException { ZooKeeper zk = new ZooKeeper("127.0.0.1", 2000, null);
Stat st = zk.exists("/goods", false);
if (st == null) {
zk.create("/goods", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
String[] goods = { "iPhone6s", "小米移动电源" };
for (String g : goods) {
zk.create("/goods/" + g, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
} int threadCount = 5;
CyclicBarrier cb = new CyclicBarrier(threadCount); // 为了更好地表示并发,这里用了CyclicBarrier类
for (int i = 0; i < threadCount; i++) {
// 用多线程摸您多用户
new Thread(new Thread1(cb)).start();
}
System.in.read(); } static class Thread1 implements Runnable {
ZooKeeper zk = null;
CyclicBarrier cb; // 是否还没有抢过商品
boolean isNotGet = true; public Thread1(CyclicBarrier cb) {
this.cb = cb;
} private void snatchGoods() throws Exception { // 获取商品库存
List<String> goodsList = zk.getChildren("/goods", true);// 获取商品列表并监控变化,如果在和其它用户抢购同一个商品时没抢到的情况下可再次监控其它商品
if (goodsList.isEmpty()) {
// 商品库存为空,表示商品抢光了
System.out.println(Thread.currentThread().getName() + "没抢到商品");
} else {
// 获取第一个商品
String goods = goodsList.get(0);
try {
// 从内存中删除商品节点,表示抢购,如果删除失败,就表示没抢到这个商品,并进入到下面的catch块中
zk.delete("/goods/" + goods, -1);
// 限制每个用户只能抢购一件商品,设置false表示已经抢购过了
isNotGet = false;
System.out.println(Thread.currentThread().getName() + "抢到了" + goods);
} catch (Exception e) { }
}
} @Override
public void run() {
try {
zk = new ZooKeeper("127.0.0.1:2181", 2000, new Watcher() {
@Override
public void process(WatchedEvent event) {
try {
EventType type = event.getType();
if (isNotGet) {
if (type == EventType.None) {
// 用户第一次访问,则立即执行商品的抢购
snatchGoods();
} else if (type == EventType.NodeChildrenChanged) {
// 抢购一件商品失败后,再抢购另一件商品
snatchGoods();
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
- 使用多线程模拟多用户抢购
- 用户第一次访问,则立即执行商品的抢购
- 抢购一件商品失败后,再抢购另一件商品
- 商品库存为空,表示商品抢光了
zookeeper实现商品秒杀抢购:
秒杀活动是一些购物平台推出的集中人气的活动,一般商品数量很少,价格很便宜,限定开始购买的时间,会在以秒为单位的时间内被购买一空。比如原价千元甚至万元的商品以一元的价格出售,但数量只有一件,在某天的某个时间开始出售,这就造成很多人去抢这一件商品。
获取商品列表并监控变化,如果在和其它用户抢购同一个商品时没抢到的情况下可再次监控其它商品
抢购一件商品失败后,再抢购另一件商品
运行多次,打印出如下结果:
Thread-4-EventThread抢到了iPhone6s
Thread-1-EventThread抢到了小米移动电源
Thread-2-EventThread没抢到商品
Thread-3-EventThread没抢到商品
Thread-0-EventThread没抢到商品 Thread-3-EventThread抢到了iPhone6s
Thread-2-EventThread抢到了小米移动电源
Thread-4-EventThread没抢到商品
Thread-1-EventThread没抢到商品
Thread-0-EventThread没抢到商品 Thread-0-EventThread抢到了iPhone6s
Thread-3-EventThread抢到了小米移动电源
Thread-4-EventThread没抢到商品
Thread-2-EventThread没抢到商品
Thread-1-EventThread没抢到商品 Thread-2-EventThread抢到了iPhone6s
Thread-4-EventThread抢到了小米移动电源
Thread-0-EventThread没抢到商品
Thread-3-EventThread没抢到商品
Thread-1-EventThread没抢到商品
可以看到,两件商品,多个线程并发抢购,总是只有两个线程分别抢到不同的商品。
zookeeper实现商品秒杀抢购的更多相关文章
- 使用Redis中间件解决商品秒杀活动中出现的超卖问题(使用Java多线程模拟高并发环境)
一.引入Jedis依赖 可以新建Spring或Maven工程,在pom文件中引入Jedis依赖: <dependency> <groupId>redis.clients< ...
- Java秒杀系统实战系列~商品秒杀代码实战
摘要: 本篇博文是“Java秒杀系统实战系列文章”的第六篇,本篇博文我们将进入整个秒杀系统核心功能模块的代码开发,即“商品秒杀”功能模块的代码实战. 内容: “商品秒杀”功能模块是建立在“商品详情”功 ...
- PHP商品秒杀问题解决方案实例详解【mysql与redis】
本文实例讲述了PHP商品秒杀问题解决方案.分享给大家供大家参考,具体如下: 引言 假设num是存储在数据库中的字段,保存了被秒杀产品的剩余数量. if($num > 0){ //用户抢购成功,记 ...
- php结合Redis实现高并发下的秒杀抢购功能
实现思路 准备两个队列A和B,假设A队列的名称为stock,用于存放商品总库存信息,B队列的名称为users,用于存放抢购成功后的用户信息.每当有用户进行抢购操作时,先从A队列弹出一个元素,如果该元素 ...
- redis使用watch完成秒杀抢购功能
Redis使用watch完成秒杀抢购功能: 使用redis中两个key完成秒杀抢购功能,mywatchkey用于存储抢购数量和mywatchlist用户存储抢购列表. 它的优点如下: 1. 首先选用内 ...
- redis使用watch完成秒杀抢购功能(转)
redis使用watch完成秒杀抢购功能: 使用redis中两个key完成秒杀抢购功能,mywatchkey用于存储抢购数量和mywatchlist用户存储抢购列表. 它的优点如下: 1. 首先选用内 ...
- PHP商品秒杀计时实现(解决大流量方案)
PHP商品秒杀功能我们多半以整点或时间点为例子,这样对于php来说处理不复杂,但有一个问题就是如果流量大要如何来处理,下面我们一起来看看解决办法. 要求要有小时分钟秒的实时倒计时的显示,用户端修改日期 ...
- redis使用watch完成秒杀抢购功能:
redis使用watch完成秒杀抢购功能: 使用redis中两个key完成秒杀抢购功能,mywatchkey用于存储抢购数量和mywatchlist用户存储抢购列表. 它的优点如下: 1. 首先选用内 ...
- 01 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之业务分析与DAO层
作者:nnngu 项目源代码:https://github.com/nnngu/nguSeckill 这是一个整合IDEA+Maven+SSM框架的高并发的商品秒杀项目.我们将分为以下几篇文章来进行详 ...
随机推荐
- Go语言 字符串
在所有编程语言中都涉及到大量的字符串操作,可见熟悉对字符串的操作是何等重要. Go中的字符串和C#中的一样(java也是),字符串内容在初始化后不可修改. 需要注意的是在Go中字符串是有UTF-8编码 ...
- 转载 在.net中使用GAC
转载出处 https://blog.log4d.com/2011/01/gac/ GAC GAC是什么?是用来干嘛的?GAC的全称叫做全局程序集缓存,通俗的理解就是存放各种.net平台下面需要使用的d ...
- Sql Server 带参数的存储过程执行方法
Sql Server 带参数的存储过程执行方法 Visual C# 动态操作 SQL Server 数据库实例教程(4):带参数的存储过程执行方法 上一篇文章介绍了带参数的SQL语句执行方法和不带参数 ...
- Process学习
主要系统总结下我对进程的认识,以前理解得不够全面不够深入.本文肯定还不够好,当有新的认识新的理解后还会随时来更新.读完本文,下面几个问题便可理解清楚. 1.进程是什么? 2.为什么要有进程这个概念? ...
- hdu 5446 Unknown Treasure lucas和CRT
Unknown Treasure Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- 关于【cocos2dx-3.0beta-制作flappybird】教程在3.2project中出现找不到CCMenuItem.h的解决方法
文章原文:http://blog.csdn.net/kantian_/article/details/36187141 作者升级源码.能够在3.1平台下执行. 我的是vs2013+cocos2dx-3 ...
- poj 1904 King's Quest tarjan求二分图的所有可选最大匹配边
因为是完美匹配,所以每个点都已经匹配了,那么如果要选择一条别的边,增光路的最后必定找到原来所匹配的点,加上匹配的边,那么就是一个环.所以可选边在一个强连通分量里. #include <iostr ...
- 从你的u盘启动:30天自制操作系统第四天u盘启动学习笔记
暑假学习小日本的那本书:30天自制操作系统 qq交流群:122358078 ,更多学习中的问题.资料,群里分享 developing environment:ubuntu 关于u盘启动自己做的操 ...
- 【转】Android LruCache源码介绍
本文来源:转载自: http://blog.csdn.net/linghu_java/article/details/8574102 package android.util; import java ...
- 有效范围为request的bean
Car.java类 package tom.jiafei; public class Car { String carnumber; String name; String date; public ...