设为首页 加入收藏

TOP

实现高并发秒杀的 7 种方式,写的太好了,建议收藏!!(六)
2023-07-25 21:25:49 】 浏览:56
Tags:高并发 方式
eckillEvent, seq, objs) -> { seckillEvent.setSeckillId((Long) objs[0]); seckillEvent.setUserId((Long) objs[1]); }; private final RingBuffer<SecondKillEvent> ringBuffer; public SecondKillEventProducer(RingBuffer<SecondKillEvent> ringBuffer){ this.ringBuffer = ringBuffer; } public void secondKill(long seckillId, long userId){ this.ringBuffer.publishEvent(translator, seckillId, userId); } } // 消费者(秒杀处理器) @Slf4j public class SecondKillEventConsumer implements EventHandler<SecondKillEvent> { private SecondKillService secondKillService = (SecondKillService) SpringUtil.getBean("secondKillService"); @Override public void onEvent(SecondKillEvent seckillEvent, long seq, boolean bool) { Result result = secondKillService.startSecondKillByAop(seckillEvent.getSeckillId(), seckillEvent.getUserId()); if(result.equals(Result.ok(SecondKillStateEnum.SUCCESS))){ log.info("用户:{}{}",seckillEvent.getUserId(),"秒杀成功"); } } } public class DisruptorUtil { static Disruptor<SecondKillEvent> disruptor; static{ SecondKillEventFactory factory = new SecondKillEventFactory(); int ringBufferSize = 1024; ThreadFactory threadFactory = runnable -> new Thread(runnable); disruptor = new Disruptor<>(factory, ringBufferSize, threadFactory); disruptor.handleEventsWith(new SecondKillEventConsumer()); disruptor.start(); } public static void producer(SecondKillEvent kill){ RingBuffer<SecondKillEvent> ringBuffer = disruptor.getRingBuffer(); SecondKillEventProducer producer = new SecondKillEventProducer(ringBuffer); producer.secondKill(kill.getSeckillId(),kill.getUserId()); } } @ApiOperation(value="秒杀实现方式七——Disruptor队列") @PostMapping("/start/disruptor") public Result startDisruptor(long skgId){ try { log.info("开始秒杀方式七..."); final long userId = (int) (new Random().nextDouble() * (99999 - 10000 + 1)) + 10000; SecondKillEvent kill = new SecondKillEvent(); kill.setSeckillId(skgId); kill.setUserId(userId); DisruptorUtil.producer(kill); } catch (Exception e) { e.printStackTrace(); } return Result.ok(); }

经过测试,发现使用Disruptor队列队列,与自定义队列有着同样的问题,也会出现超卖的情况,但效率有所提高。

4. 小结

对于上面七种实现并发的方式,做一下总结:

  • 一、二方式是在代码中利用锁和事务的方式解决了并发问题,主要解决的是锁要加载事务之前
  • 三、四、五方式主要是数据库的锁来解决并发问题,方式三是利用for upate对表加行锁,方式四是利用update来对表加锁,方式五是通过增加version字段来控制数据库的更新操作,方式五的效果最差
  • 六、七方式是通过队列来解决并发问题,这里需要特别注意的是,在代码中不能通过throw抛异常,否则消费线程会终止,而且由于进队和出队存在时间间隙,会导致商品少卖

上面所有的情况都经过代码测试,测试分一下三种情况:

  • 并发数1000,商品数100
  • 并发数1000,商品数1000
  • 并发数2000,商品数1000

思考:分布式情况下如何解决并发问题呢?下次继续试验。

版权声明:本文为CSDN博主「止步前行」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/zxd1435513775/article/details/122643285

近期热文推荐:

1.1,000+ 道 Java面试题及答案整理(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!

首页 上一页 3 4 5 6 下一页 尾页 6/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇存下吧!Spring高频面试题总结 下一篇Spring MVC官方文档学习笔记(一..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目