java什么是超卖现象?

当出现  商品的销售量 > 实际的库存量 的现象 成为“超卖”

解释:假设某商品X卖剩下最后一件,线程A(客户)进来下单,下单完成,还没来得及减库存,这时线程B又进来了,判断还有库存,继续下单,这时出现超卖,库存实际有一件商品,却卖出了2件商品

package com.dj.springtest.demo;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * User: ldj
 * Date: 2024/4/12
 * Time: 19:08
 * Description: 超卖测试
 * (悲观锁synchronized)
 * (乐观锁CAS: update tb_ticket set number = number - 1 where ticket_id = ? and number > 0)缺点不会走索引
 */
public class OversoldDemo {

    public static void main(String[] args) {

        Ticket ticket = new Ticket();
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    countDownLatch.await();
                    //ticket.sale1();
                    //ticket.sale2();
                    ticket.sale3();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "顾客" + i).start();
            countDownLatch.countDown();
        }
    }
}

class Ticket {

    //剩下最后一张票
    private int tickets = 1;
    //可重入锁(默认非公平,减少cpu来回切换的开销)
    ReentrantLock reentrantLock = new ReentrantLock(true);

    public void sale1() throws InterruptedException {
        if (tickets > 0) {
            //模拟还没来得及减库存
            TimeUnit.SECONDS.sleep(2);
            tickets = tickets - 1;
            System.out.println("[" + Thread.currentThread().getName() + "]抢票成功" + "目前还剩" + tickets);
        } else {
            System.out.println("[" + Thread.currentThread().getName() + "]真抱歉!票已经售罄");
        }
    }

    //集群部署情况还是会出现超卖现象,需要使用分布式锁
    public synchronized void sale2() {
        if (tickets > 0) {
            tickets = tickets - 1;
            System.out.println("[" + Thread.currentThread().getName() + "]抢票成功" + "目前还剩" + tickets);
        } else {
            System.out.println("[" + Thread.currentThread().getName() + "]真抱歉!票已经售罄");
        }
    }

    //集群部署情况还是会出现超卖现象,需要使用分布式锁
    public void sale3() {
        reentrantLock.lock();
        try {
            if (tickets > 0) {
                tickets = tickets - 1;
                System.out.println("[" + Thread.currentThread().getName() + "]抢票成功" + "目前还剩" + tickets);
            } else {
                System.out.println("[" + Thread.currentThread().getName() + "]真抱歉!票已经售罄");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            reentrantLock.unlock();
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值