• springboot单机秒杀之queue队列


    一:

    queue队列,类似水管,水从入口进从水龙头出,水龙头要一直着水就会出来,没有水就会等水出来。

    所以我们用到两个方法,

    添加和取值。

    add        增加一个元索                     如果队列已满,则抛出一个IIIegaISlabEepeplian异常
    
    put         添加一个元素                      如果队列满,则阻塞

    因为我们是秒杀,我们指定队列长度后不需要它阻塞。队列长度就是请求的成功数。

      

      poll         移除并返问队列头部的元素    如果队列为空,则返回null
    
      remove     移除并返回队列头部的元素    如果队列为空,则抛出一个NoSuchElementException异常
    
      take        移除并返回队列头部的元素     如果队列为空,则阻塞

    我们用take一直阻塞。

    2:

    /**
     * 队列工具类
     *
     * @author jiang
     */
    public class QueueUtil {
    
    
        /**
         * 初始化有界队列队列
         */
        private static final LinkedBlockingQueue<String> LINKED_BLOCKING_QUEUE = new LinkedBlockingQueue<String>(100);
    
    
        public static boolean add(String killId) {
            try {
    
                LINKED_BLOCKING_QUEUE.add(killId);
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    
        public static Optional<String> take() {
    
            String killId = null;
            try {
                killId = LINKED_BLOCKING_QUEUE.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Optional.ofNullable(killId);
        }
     @GetMapping("/startKill2")
        public R startKill2(String killId) {
            if (QueueUtil.add(killId)) {
                return R.ok();
            }
            return R.error();
        }
    **
     * 项目启动时加载
     */
    @Component
    @Slf4j
    public class MyApplicationRunner implements ApplicationRunner {
    
        @Autowired
        private ISeckillService seckillService;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
    
            log.info("项目初始化加载");
    
            while (true) {
                Optional<String> killId = QueueUtil.take();
                killId.ifPresent(s -> seckillService.startKill(s));
            }
        }
    }
    @Override
        @Transactional(rollbackFor = Exception.class)
        public R startKill(String killId) {
    
            Seckill seckill = this.getOne(new LambdaQueryWrapper<Seckill>().eq(Seckill::getSeckillId, killId));
            int number = seckill.getNumber();
            if (number > 0) {
                Seckill seckill1 = seckill.setNumber(--number);
                this.update(seckill1, new LambdaQueryWrapper<Seckill>().eq(Seckill::getSeckillId, seckill.getSeckillId()));
    
                SuccessKilled successKilled = new SuccessKilled();
                successKilled.setCreateTime(new Date());
                successKilled.setSeckillId(Long.parseLong(killId));
                successKilled.setState(0);
                successKilledMapper.insert(successKilled);
                return R.ok();
            }
            return R.error("没有了!");
    
        }
  • 相关阅读:
    数据库设计规则
    了解何时使用 Override 和 New 关键字(C# 编程指南)
    Why we use stored procedure than Sql statement?
    HTML条件注释和javascript条件注释
    <%# %> 和 <% %> 有什么区别?
    short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
    如何实现 Visual Studio 2005 中远程调试
    认识延迟时间为0的setTimeout(转)
    Web应用程序中(VS2005+SP1)添加App_Code
    AWStats 一个不错的Web/Mail/FTP日志分析工具
  • 原文地址:https://www.cnblogs.com/bchange/p/12761615.html
Copyright © 2020-2023  润新知