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("没有了!");

    }

 

posted @ 2020-04-23 16:16  jwcc  阅读(4234)  评论(0编辑  收藏  举报