java中用redis实现分布式计数应优先使用incr命令,因其自动初始化、原子递增、线程安全;配合set初始化非零起点,expire/setex实现带过期的临时计数,注意jedis连接池管理、类型转换及异常降级。

Java 中用 Redis 处理分布式计数,核心就是靠 String 类型的 SET、GET 和原子性命令 INCR。关键不在于存数字,而在于用对命令——INCR 自动初始化、自动加 1、线程安全,这才是分布式环境下不出错的根基。
用 INCR 实现“开箱即用”的计数器
INCR 是最推荐的起点。它会自动判断 key 是否存在:不存在就设为 0 再 +1,存在就直接 +1,全程原子执行,无需额外判断或加锁。
- 每次调用
jedis.incr("order:count"),返回值就是自增后的新数值(比如从 99 变成 100) - 不需要先
GET判断是否存在,也不用担心并发写覆盖 - 适合阅读量、订单号、API 调用次数等纯递增场景
SET 和 GET 配合 INCR 的典型组合
有些场景需要预设初始值或非零起点(比如库存初始为 100),这时可先用 SET 初始化,再用 INCR/DECR 操作:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 初始化:
jedis.set("stock:item123", "100") - 扣减库存:
jedis.decr("stock:item123")(返回 99) - 查当前值:
jedis.get("stock:item123")→ 返回 "99" - 注意:
SET存的是字符串,但INCR/DECR会自动转为整数运算;若值不是纯数字,会报错(ERR value is not an integer)
带过期时间的临时计数器(如限流)
对按时间窗口统计的计数(如“每分钟最多 60 次请求”),建议搭配 EXPIRE 或 SETEX 使用:
- 用时间戳拼 key:
"req:192.168.1.100:2026072013"(IP + 小时) - 设置并带过期:
jedis.setex("req:192.168.1.100:2026072013", 3600, "0") - 之后用
jedis.incr("req:192.168.1.100:2026072013")累加,超时自动清理,不占内存
Java 代码中要注意的细节
实际编码时,几个容易踩坑的地方:
- Jedis 实例建议用连接池管理(如 JedisPool),避免频繁创建销毁连接
-
incr返回long,get返回String,类型转换要小心(比如Long.parseLong(jedis.get(key))前需判空) - 生产环境建议加 try-catch,并对 Redis 连接异常做降级(如返回默认值或走本地缓存)
- 如果要用浮点数计数,选
INCRBYFLOAT,它支持小数增量,且同样原子
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










