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

    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM