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框架的高并发的商品秒杀项目.我们将分为以下几篇文章来进行详 ...
随机推荐
- 获取本机IP地址和MAC地址
unit NetFunc; interface uses SysUtils, Windows, dialogs, winsock, Classes, ComObj, WinInet, Variants ...
- Umbraco中的权限体系结构
分为管理用户体系,和成员用户体系,也就是 Users(用户)和Members(成员). 2.1. Users(用户) 用户是对功能操作权限定义的,首先看一下所有Action的Permissions: ...
- Head First设计模式-观察者模式
一.整体代码 Subject.java public interface Subject { public void registerObserver(Observer o); public void ...
- iOS- iPad UIPopoverController
在IPAD开发中,有一个很有趣的视图控制器,UIPopoverControllr,它的初始化必须要设置一个"内容视图",相当于它本身只是作为一个“容器”,而显示的内容还需要另外一个 ...
- Project Management - 2) Estimate Your Work
1. Delphi估算 1) 项目经理召集小组成员,就项目有关事宜向大家进行阐述. 2)大家提出各种问题,然后进行分配任务. 每个人写下自己的任务列表和时间估算. 3)项目经理收集好任务之后进行复查, ...
- 微信公众平台java开发详解(工程代码+解析)
原文:http://blog.csdn.net/pamchen/article/details/38718947 说明:本次的教程主要是对微信公众平台开发者模式的讲解,网络上很多类似文章,但很多都让初 ...
- SICP 习题 (1.14)解题总结
SICP 习题 1.14要求计算出过程count-change的增长阶.count-change是书中1.2.2节讲解的用于计算零钱找换方案的过程. 要解答习题1.14,首先你需要理解count-ch ...
- ios开发——实战OC篇&FMDB详解
FMDB详解 前一篇文章中我们介绍的SQLite的使用,在iOS中原生的SQLite API在使用上相当不友好. 于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.Plausibl ...
- android学习日记03--常用控件button/imagebutton
常用控件 控件是对数据和方法的封装.控件可以有自己的属性和方法.属性是控件数据的简单访问者.方法则是控件的一些简单而可见的功能.所有控件都是继承View类 介绍android原生提供几种常用的控件bu ...
- LLBLGen代码生成工具
LLBLGen代码生成工具 下载地址:http://www.llblgen.com/ 最新版本4.2 概述 LLBLGen是一个数据访问的解决方案; 你使用LLBLGen创建实体/域模型,定义了映射和 ...