概述
Redisson 中的 RFuture 是其所有异步 API 的“统一返回类型”,它屏蔽了 Netty 本身的 Future/Promise 细节,同时又兼容 Java 8 的 CompletableFuture,使得异步、同步、链式、组合等各种使用姿势都能平滑切换。下面从“设计原理 核心能力 典型用法 注意事项”四个维度做一次性梳理,方便日后查阅
一、设计原理
类图位置RFuture ────┬──── RedissonPromise(唯一实现)└──── 继承自 Netty 的 DefaultPromise,再包装了 CompletableFuture 的能力,因此同时拥有:• Netty 的 listener / await 机制(低延迟高并发)• CompletableFuture 的 thenApply / thenCompose / whenComplete 链式 API异步链路业务线程 Netty I/O 线程(发送 Redis 命令) Redis 返回结果 同一个 EventLoop 线程回调 operationComplete() 设置 RFuture 结果 触发用户 listener 结束。线程模型• 所有真正跟 Redis 的 I/O 都在 Netty EventLoop 中完成,业务线程不会被阻塞;• 只有当你显式调用 get()、await() 时才会阻塞;• 回调函数(listener、whenComplete…)默认在 EventLoop 中执行,因此不要放耗时逻辑,否则会拖慢整个 Reactor 线程。
二、核心能力
三、典型用法示例
1.异步拿锁 + 自动续期
RLocklock= redisson.getLock("pay:123");RFuture<Void> lockFuture = lock.lockAsync(30, TimeUnit.SECONDS);lockFuture.whenComplete((nil, ex) -> {if (ex != null) { log.error("加锁失败", ex);return; }try {// 业务逻辑 } finally { lock.unlockAsync(); // 也是返回 RFuture<Void> }});
2.链式组合:先写缓存再发消息
RFuture<Void> writeCache = redisson.getBucket("k").setAsync("v");RFuture<Long> publishMsg = writeCache.thenCompose(v -> redisson.getTopic("notice").publishAsync("hello"));
3.同步兜底(启动脚本、单元测试)
Stringvalue= bucket.getAsync("k").toCompletableFuture().join();
四、常见“坑”与最佳实践
1.不要在回调里阻塞
whenComplete 默认跑在 Netty I/O 线程,请把耗时或可能阻塞的操作丢到业务线程池,否则整个 Redisson client 会被拖慢。
2.正确理解“取消”
RFuture.cancel(true) 只能中断客户端等待,Redis 命令已经发出就停不下来;如果业务需要“撤销”逻辑,必须自己写补偿脚本。转换到 CompletableFutureRFuture 实现了 CompletionStage,可直接 toCompletableFuture() 拿到 Java 8 原生对象,与 Spring WebFlux、Project Reactor 无缝衔接。
3.监听器执行顺序
Netty 的 listener 按添加顺序同步执行,不要依赖线程切换带来的可见性;如需并发处理,自行提交到线程池。
五.一句话总结
RFuture = Netty Future + CompletableFuture,它把 Redis 的高性能网络 I/O 与 Java 的异步编程模型完美黏合在一起,只要遵循“Reactor 线程不阻塞”这一条铁律,就可以在 Redisson 里写出既优雅又高效的分布式代码。