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框架的高并发的商品秒杀项目.我们将分为以下几篇文章来进行详 ...
随机推荐
- linux磁盘简单分区方式
1:分区 fdisk /dev/sdb 2:格式化 mkfs -t ext3 /dev/sdb1 或者 mke2fs -t ext4 /dev/sdb2 3:挂载 mount /dev/sdb1 ...
- 如何使用IAR仿真环境查看CPU类型字长?
在此操作之前假设已有一个现成的cpu代码工程如:IAR for Stm8的Demo工程. 点软件仿真进入调试状态 单击菜单栏View –> Watch –> Watch 在新弹出来的Wat ...
- js调试工具Console命令详解
这篇文章主要介绍了js调试工具Console命令详解,需要的朋友可以参考下 一.显示信息的命令 复制代码 代码如下: < !DOCTYPE html> < html> &l ...
- jq向上无缝滚动
<!-- -------------摇奖排行榜--------------- --> <div class="Top_Record"> <div cl ...
- Python中raw字符串与多行字符串
如果一个字符串包含很多需要转义的字符,对每一个字符都进行转义会很麻烦.为了避免这种情况,我们可以在字符串前面加个前缀r ,表示这是一个 raw 字符串,里面的字符就不需要转义了.例如: r'\(~_~ ...
- Microsoft .NET Pet Shop 4
Microsoft .NET Pet Shop 4:将 ASP.NET 1.1 应用程序迁移到 2.0 299(共 313)对本文的评价是有帮助 - 评价此主题 发布日期 : 2006-5-9 | 更 ...
- Eclipse+Maven构建web项目及部署时Maven lib依赖问题的解决
目录 Eclipse中m2e插件构建web项目的步骤 Maven工具构建web项目再导入Eclipse的步骤 [一].Eclipse中m2e插件构建web项目的步骤 第一步:创建项目,按照 New – ...
- C++ 变量初始化规则
1.定义变量的时候,如果没有初始化,它的值是什么呢? 它的值取决于变量的类型和变量定义的位置. 2.考虑基本类型的变量,定义时没有初始化.如果定义在方法外部,初始化为0,如果定义在方法内部,不被初始化 ...
- 关于expanded一级二级菜单数据的分组排序
最新再弄关于expandedlistview相关的东西,所以需求是需要对一级菜单根据时间排序,同时二级菜单也需要根据时间排序,距离现在最近的时间显示在最前面. 效果就是如下: --group2 -- ...
- Tricks Device (hdu 5294 最短路+最大流)
Tricks Device Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) To ...