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

相关推荐
好好沉淀6 分钟前
ES 脚本核心语法:ctx._source [‘group_id‘]
java·elasticsearch·script
李慕婉学姐29 分钟前
【开题答辩过程】以《基于Spring Boot的疗养院理疗管理系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·spring boot·后端
tb_first34 分钟前
SSM速通2
java·javascript·后端
qq_124987075337 分钟前
基于协同过滤算法的运动场馆服务平台设计与实现(源码+论文+部署+安装)
java·大数据·数据库·人工智能·spring boot·毕业设计·计算机毕业设计
大飞哥~BigFei39 分钟前
自定义注解记录接口切面log日志入库优化
java
人道领域40 分钟前
javaWeb从入门到进阶(maven高级进阶)
java·spring·maven
一路向北⁢42 分钟前
Spring Boot 3 整合 SSE (Server-Sent Events) 企业级最佳实践(一)
java·spring boot·后端·sse·通信
风象南1 小时前
JFR:Spring Boot 应用的性能诊断利器
java·spring boot·后端
数据知道1 小时前
PostgreSQL 核心原理:读已提交与可重复读的底层实现差异(事务隔离级别)
数据库·postgresql
crossaspeed1 小时前
MySQL的MVCC
数据库·mysql