【无标题】

package homework;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.;
import java.util.concurrent.
;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;

import static homework.common.Global.*;

public class ShopClient {
private static final Logger LOGGER = LoggerFactory.getLogger(ShopClient.class);

private static final Random RANDOM = new Random();
// 商品存储
private static final Map<Integer, Good> GOODS_STORE = new ConcurrentHashMap<>();
// 用户集合
private static final Map<Integer, User> USER_MAP = new ConcurrentHashMap<>();

// 抢购线程池
private static final ExecutorService THREAD_POOL = new ThreadPoolExecutor(
        CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue<>(THREAD_QUEUE_CAPACITY)
);

/***
 * 抢购活动
 * result[0] 返回商品种类数量
 * result[1] 返回商品购买次数
 * result[2] 返回商品减少数量
 */
public static List<Integer> snapUpActive() {
    List<Integer> results = new ArrayList<>();
    init();
    // 计算原始的商品种类的数量
    int goodTypeNum = getGoodsTypeNum();
    LOGGER.info("抢购开始前,商品总数为{}", goodTypeNum);
    // 商品种类数量
    Integer goodsTypeCount = GOODS_STORE.size();
    // 商品购买次数
    AtomicInteger buyCount = new AtomicInteger(0);
    // 商品减少数量
    AtomicInteger reduceCount = new AtomicInteger(0);
    try {
        // 初始化商品信息

        // 执行抢购活动
        long l = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            User user = USER_MAP.get(RANDOM.nextInt(USER_MAP.size()) + 1);
            THREAD_POOL.submit(new StoreThread(user, buyCount, reduceCount));
        }
        THREAD_POOL.shutdown();
        System.out.println(System.currentTimeMillis() - l);
        goodsTypeCount = getGoodsTypeNum();
        // 运行后数据校验
        results.add(goodsTypeCount);
        results.add(buyCount.get());
        results.add(reduceCount.get());
        LOGGER.info("总数统计{},{},{}", goodsTypeCount, buyCount.get(), reduceCount.get());
    } catch (Exception e) {
        e.printStackTrace();
        System.err.println("抢购活动运行报错");
    }
    return results;
}


private static int getGoodsTypeNum() {
    int goodTypeNum = 0;
    Set<Map.Entry<Integer, Good>> entries = GOODS_STORE.entrySet();
    for (Map.Entry<Integer, Good> entry : entries) {
        goodTypeNum += entry.getValue().getGoodAmount().get();
    }
    return goodTypeNum;
}

public static void init() {
    // 缓存商品信息
    GOODS_STORE.put(1, new Good(1, "华为手机", new AtomicInteger(1200), 2));
    GOODS_STORE.put(2, new Good(2, "耳机", new AtomicInteger(2000), 2));
    GOODS_STORE.put(3, new Good(3, "iPhone 20 pro max", new AtomicInteger(1500), 5));
    GOODS_STORE.put(4, new Good(4, "iPad", new AtomicInteger(1300), 1));
    GOODS_STORE.put(5, new Good(5, "电竞椅", new AtomicInteger(1000), 8));
    GOODS_STORE.put(6, new Good(6, "OPPO手机", new AtomicInteger(1100), 1));
    GOODS_STORE.put(7, new Good(7, "红米手机", new AtomicInteger(2500), 5));
    GOODS_STORE.put(8, new Good(8, "电吹风", new AtomicInteger(3000), 1));
    GOODS_STORE.put(9, new Good(9, "餐巾纸", new AtomicInteger(2500), 5));
    GOODS_STORE.put(10, new Good(10, "电动车", new AtomicInteger(5000), 2));
    // 缓存用户信息
    USER_MAP.put(1, new User(1, "zhangsan", new AtomicInteger(5000)));
    USER_MAP.put(2, new User(2, "lisi", new AtomicInteger(5000)));
    USER_MAP.put(3, new User(3, "wangwang", new AtomicInteger(5000)));
    USER_MAP.put(4, new User(4, "hh", new AtomicInteger(5000)));
    USER_MAP.put(5, new User(5, "xioami", new AtomicInteger(5000)));
}

/**
 * 通过内部类StoreThread模拟抢购行为
 */
private static class StoreThread implements Runnable {
    private final User user;
    private final AtomicInteger buyCount;
    private final AtomicInteger reduceCount;

    public StoreThread(User user, AtomicInteger buyCount, AtomicInteger reduceCount) {
        this.user = user;
        this.buyCount = buyCount;
        this.reduceCount = reduceCount;
    }

    @Override
    public void run() {
        // if (user.getUserPoints().get() <= 0) {
        //     LOGGER.warn("用户 {} 购买失败,积分不足,当前用户积分为{}", user.getUserName(), user.getUserPoints().get());
        //     return;
        // }
        // int productId = RANDOM.nextInt(GOODS_STORE.size()) + 1;
        // Good product = GOODS_STORE.get(productId);
        // synchronized (product) {
        //     if (user.getUserPoints().get() < product.getPoint()) {
        //         LOGGER.warn("用户 {} 购买 {} 失败,积分不足,当前用户积分为{}", user.getUserName(), product.getGoodInfo(), user.getUserPoints().get());
        //     } else if (product.getGoodAmount().get() <= 0) {
        //         LOGGER.warn("用户 {} 购买 {} 失败,库存不足,当前商品库存为{}", user.getUserName(), product.getGoodInfo(), product.getGoodAmount().get());
        //     } else {
        //         user.getUserPoints().getAndAdd(-product.getPoint());
        //         product.getGoodAmount().decrementAndGet();
        //         buyCount.incrementAndGet();
        //         reduceCount.incrementAndGet();
        //         LOGGER.info("用户 {} 成功购买了 {},当前积分{},当前库存{}", user.getUserName(), product.getGoodInfo(), user.getUserPoints(), product.getGoodAmount());
        //     }
        // }
        if (user.getUserPoints().get() <= 0) {
            LOGGER.warn("用户 {} 购买失败,积分不足,当前用户积分为{}", user.getUserName(), user.getUserPoints().get());
            return;
        }
        int productId = RANDOM.nextInt(GOODS_STORE.size()) + 1;
        Good product = GOODS_STORE.get(productId);

        // 尝试购买商品,直到成功或积分不足
        while (true) {
            int currentPoints = user.getUserPoints().get();
            int currentAmount = product.getGoodAmount().get();

            // 检查积分和库存是否足够
            if (currentPoints < product.getPoint() || currentAmount <= 0) {
                LOGGER.warn("用户 {} 购买 {} 失败,积分不足或库存不足", user.getUserName(), product.getGoodInfo());
                break;
            }

            // 使用 compareAndSet 进行乐观锁操作
            boolean pointsUpdated = user.getUserPoints().compareAndSet(currentPoints, currentPoints - product.getPoint());
            boolean amountUpdated = product.getGoodAmount().compareAndSet(currentAmount, currentAmount - 1);

            if (pointsUpdated && amountUpdated) {
                buyCount.incrementAndGet();
                reduceCount.incrementAndGet();
                LOGGER.info("用户 {} 成功购买了 {},当前积分{},当前库存{}", user.getUserName(), product.getGoodInfo(), user.getUserPoints(), product.getGoodAmount());
                break; // 购买成功,退出循环
            }
        }
    }
    //
    }


public static void main(String[] args) {
    List<Integer> results = snapUpActive();
    System.out.println("商品种类数量: " + results.get(0));
    System.out.println("商品购买次数: " + results.get(1));
    System.out.println("商品减少数量: " + results.get(2));
}

}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值