java秒杀怎么防止超卖_如何防止秒杀抢购超卖?

1 packagecom.github.distribute.lock.redis;2

3 importjava.util.List;4 importjava.util.Set;5 importjava.util.concurrent.ExecutorService;6 importjava.util.concurrent.Executors;7

8 importredis.clients.jedis.Jedis;9 importredis.clients.jedis.Transaction;10

11 /**

12 * redis乐观锁实例13 *@authorlinbingwen14 *15 */

16 public classOptimisticLockTest {17

18 public static void main(String[] args) throwsInterruptedException {19 long starTime=System.currentTimeMillis();20

21 initPrduct();22 initClient();23 printResult();24

25 long endTime=System.currentTimeMillis();26 long Time=endTime-starTime;27 System.out.println("程序运行时间: "+Time+"ms");28

29 }30

31 /**

32 * 输出结果33 */

34 public static voidprintResult() {35 Jedis jedis =RedisUtil.getInstance().getJedis();36 Set set = jedis.smembers("clientList");37

38 int i = 1;39 for(String value : set) {40 System.out.println("第" + i++ + "个抢到商品,"+value + " ");41 }42

43 RedisUtil.returnResource(jedis);44 }45

46 /*

47 * 初始化顾客开始抢商品48 */

49 public static voidinitClient() {50 ExecutorService cachedThreadPool =Executors.newCachedThreadPool();51 int clientNum = 10000;//模拟客户数目

52 for (int i = 0; i < clientNum; i++) {53 cachedThreadPool.execute(newClientThread(i));54 }55 cachedThreadPool.shutdown();56

57 while(true){58 if(cachedThreadPool.isTerminated()){59 System.out.println("所有的线程都结束了!");60 break;61 }62 try{63 Thread.sleep(1000);64 } catch(InterruptedException e) {65 e.printStackTrace();66 }67 }68 }69

70 /**

71 * 初始化商品个数72 */

73 public static voidinitPrduct() {74 int prdNum = 100;//商品个数

75 String key = "prdNum_100001";76 String clientList = "clientList";//抢购到商品的顾客列表

77 Jedis jedis =RedisUtil.getInstance().getJedis();78

79 if(jedis.exists(key)) {80 jedis.del(key);81 }82

83 if(jedis.exists(clientList)) {84 jedis.del(clientList);85 }86

87 jedis.set(key, String.valueOf(prdNum));//初始化

88 RedisUtil.returnResource(jedis);89 }90

91 }92

93 /**

94 * 顾客线程95 *96 *@authorlinbingwen97 *98 */

99 class ClientThread implementsRunnable {100 Jedis jedis = null;101 String key = "prdNum_10001";//商品主键

102 String clientList = "clientList";抢购到商品的顾客列表主键

103 String clientName;104

105 public ClientThread(intnum) {106 clientName = "编号=" +num;107 }108

109 public voidrun() {110 try{111 Thread.sleep((int)(Math.random()*5000));//随机睡眠一下

112 } catch(InterruptedException e1) {113 }114 while (true) {115 System.out.println("顾客:" + clientName + "开始抢商品");116 jedis =RedisUtil.getInstance().getJedis();117 try{118 jedis.watch(key);119 int prdNum = Integer.parseInt(jedis.get(key));//当前商品个数

120 if (prdNum > 0) {121 Transaction transaction =jedis.multi();122 transaction.set(key, String.valueOf(prdNum - 1));123 List result =transaction.exec();124 if (result == null ||result.isEmpty()) {125 System.out.println("悲剧了,顾客:" + clientName + "没有抢到商品");//可能是watch-key被外部修改,或者是数据操作被驳回

126 } else{127 jedis.sadd(clientList, clientName);//抢到商品记录一下

128 System.out.println("好高兴,顾客:" + clientName + "抢到商品");129 break;130 }131 } else{132 System.out.println("悲剧了,库存为0,顾客:" + clientName + "没有抢到商品");133 break;134 }135 } catch(Exception e) {136 e.printStackTrace();137 } finally{138 jedis.unwatch();139 RedisUtil.returnResource(jedis);140 }141

142 }143 }144

145 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值