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

相关推荐
LSL666_13 小时前
1 概述及简单登录(不涉及数据库)
数据库·servlet
一只会写代码的猫13 小时前
面向高性能计算与网络服务的C++微内核架构设计与多线程优化实践探索与经验分享
java·开发语言·jvm
萤丰信息14 小时前
智慧园区能源革命:从“耗电黑洞”到零碳样本的蜕变
java·大数据·人工智能·科技·安全·能源·智慧园区
曹牧14 小时前
Eclipse为方法添加注释
java·ide·eclipse
我叫张小白。15 小时前
Spring Boot拦截器详解:实现统一的JWT认证
java·spring boot·web·jwt·拦截器·interceptor
q***064716 小时前
MySQL的UPDATE(更新数据)详解
数据库·mysql
8***B16 小时前
MySQL性能
数据库·mysql
q***721916 小时前
oracle使用PLSQL导出表数据
数据库·oracle
数据库生产实战16 小时前
Oracle DG备库日志切换解析,Private strand flush not complete如何理解?(基础知识)
数据库·oracle
百***757416 小时前
从 SQL 语句到数据库操作
数据库·sql·oracle