用 Redis 的 List 存储库存队列,并通过 LPOP 原子性出队来保证并发安全案例

Jedis 作为 Redis 客户端库(简单易用),实现一个模拟秒杀库存扣减的案例。

Java 代码示例

java 复制代码
import redis.clients.jedis.Jedis;

public class RedisStockQueue {

    private static final String STOCK_KEY = "product:1001:stock";

    public static void main(String[] args) {
        // 连接 Redis
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        jedis.auth("your_password"); // 如果有密码

        // 初始化库存队列(假设库存 5 件)
        initStock(jedis, 5);

        // 模拟多个用户并发抢购
        for (int i = 1; i <= 10; i++) {
            String userId = "user_" + i;
            new Thread(() -> {
                String result = buyProduct(jedis, userId);
                System.out.println(userId + " -> " + result);
            }).start();
        }

        jedis.close();
    }

    /**
     * 初始化库存队列
     */
    private static void initStock(Jedis jedis, int stockCount) {
        jedis.del(STOCK_KEY); // 清空旧库存
        for (int i = 1; i <= stockCount; i++) {
            jedis.rpush(STOCK_KEY, "stock_" + i);
        }
        System.out.println("库存初始化完成,数量:" + stockCount);
    }

    /**
     * 用户抢购商品
     */
    private static String buyProduct(Jedis jedis, String userId) {
        // LPOP 原子性出队
        String stockItem = jedis.lpop(STOCK_KEY);
        if (stockItem != null) {
            return "抢购成功,获得库存:" + stockItem;
        } else {
            return "抢购失败,库存已空";
        }
    }
}

代码说明

  1. 库存初始化

    • RPUSH 将库存数据压入 Redis List,例如 stock_1stock_2...
    • List 的顺序可以代表库存的唯一标识。
  2. 抢购逻辑

    • LPOP 从队列头部取出一个库存项。
    • LPOP 是 Redis 的原子操作,即使多个线程同时执行,也不会出现超卖。
  3. 并发安全

    • Redis 的单线程模型保证了 LPOP 的原子性,不需要额外加锁。

运行效果示例

假设库存是 5 件,10 个用户同时抢购,输出可能是:

库存初始化完成,数量:5

user_1 -> 抢购成功,获得库存:stock_1

user_3 -> 抢购成功,获得库存:stock_2

user_5 -> 抢购成功,获得库存:stock_3

user_2 -> 抢购成功,获得库存:stock_4

user_4 -> 抢购成功,获得库存:stock_5

user_6 -> 抢购失败,库存已空

user_7 -> 抢购失败,库存已空

user_8 -> 抢购失败,库存已空

user_9 -> 抢购失败,库存已空

user_10 -> 抢购失败,库存已空

相关推荐
咖啡八杯9 小时前
GoF设计模式——策略模式
java·后端·spring·设计模式
用户1285261160217 小时前
我把祖传Java项目重构后,接口响应从3s砍到了200ms,只改了这几行代码
java
Linsk17 小时前
组件 = 模板 + 业务逻辑
java·前端·vue.js
Nturmoils18 小时前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
星沉远浦18 小时前
用Gemini高效解决Java代码报错难以定位的问题
java
用户298698530141 天前
Word 文档字符级格式化:Java 实现方案详解
java·后端
渣波1 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
笨鸟飞不快1 天前
从单个服务到集群:一次完整的性能排查复盘
java·前端
荣码1 天前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python
SamDeepThinking1 天前
Java微服务练习方式
java·后端·微服务