用 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 -> 抢购失败,库存已空

相关推荐
皮皮林5513 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河4 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
桦说编程6 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
躺平大鹅8 小时前
Java面向对象入门(类与对象,新手秒懂)
java
初次攀爬者9 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺9 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
倔强的石头_9 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
Derek_Smart10 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP11 小时前
MyBatis-mybatis入门与增删改查
java