You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何为Redis键存储List/Set类型数据并保证线程安全?

方案实现与解答

完全可以使用Redis的List类型实现该需求,且Redis原生操作的原子性可以天然保证线程安全,比你当前逗号拼接字符串的实现方案性能、并发安全性都更高。

原方案的问题

你当前的实现存在两个明显缺陷:

  • Java层面的synchronized锁只能保证单JVM实例内的线程安全,如果是多实例部署的场景,不同实例同时读写Redis的USERS键依然会出现并发覆盖的问题
  • 每次操作都需要全量读取字符串、拼接、再全量写回,随着存储的ID数量增多,操作开销会线性上涨

List类型实现方案

Redis原生的RPUSH命令天然匹配你的需求:当目标键不存在时,会自动创建空列表再追加元素;当目标键已经是列表类型时,会直接在列表尾部追加元素,且Redis单线程处理命令的特性保证了单个RPUSH操作的原子性,全局线程安全,不需要在应用层额外加锁。

代码示例

Spring Data Redis 版本

public void pushIdInRedis(String id) {
    // rightPush 对应Redis的RPUSH命令
    redisTemplate.opsForList().rightPush("USERS", id);
}

Jedis 版本

public void pushIdInRedis(String id) {
    try (Jedis jedis = jedisPool.getResource()) {
        jedis.rpush("USERS", id);
    }
}

方案优势

  • 操作性能更高:RPUSH是O(1)时间复杂度的操作,无论列表存储的ID数量有多少,追加操作的耗时都保持稳定
  • 全局线程安全:Redis命令的原子性不受应用实例部署数量影响,多实例并发操作也不会出现数据覆盖、丢失的问题
  • 后续维护更方便:如果后续需要遍历ID、弹出头部ID、删除指定ID等操作,直接调用LRANGE/LPOP/LREM等Redis原生命令即可,不需要自行拆分处理逗号拼接的字符串。

如果你的业务要求存储的用户ID不能重复,可以替换使用Redis的Set类型,调用SADD命令,同样支持原子操作、不存在自动创建的特性,还能自动实现ID去重。

内容的提问来源于stack exchange,提问作者imsaiful

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 13:00:02