java泛型分布式锁模板通过lockexecutor接口解耦资源标识、业务逻辑与锁客户端,withlock方法自动处理加锁、执行、释放及异常清理,支持类型安全、自动推导与灵活扩展。

Java 中用泛型实现通用的分布式锁包装,核心是把锁的资源标识(key)、业务逻辑(需加锁执行的操作)、以及底层分布式锁客户端(如 Redisson、Curator)解耦,通过泛型参数统一类型处理,避免重复模板代码。
定义泛型锁执行接口
先抽象出一个可复用的执行契约,让调用方只关注「做什么」,不关心「怎么锁」:
public interface LockExecutor<t> {
T execute();
}</t>
这个接口接收无参、返回泛型结果,后续可配合 Lambda 简洁传入业务逻辑。
封装泛型分布式锁模板方法
以 Redisson 为例(其他客户端逻辑类似),写一个通用的 withLock 方法:
- 泛型参数 R 表示业务方法的返回类型
- 入参包括:锁 key(String)、过期时间(long)、时间单位(TimeUnit)、实际要执行的逻辑(LockExecutor
) - 内部自动获取锁、执行、释放锁,并处理异常时的锁清理
示例实现:
public class DistributedLockTemplate {
private final RedissonClient redissonClient;
public DistributedLockTemplate(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}
public <r> R withLock(String lockKey, long leaseTime, TimeUnit unit,
LockExecutor<r> executor) {
R result = null;
RLock lock = redissonClient.getLock(lockKey);
try {
if (lock.tryLock(0, leaseTime, unit)) {
result = executor.execute();
} else {
throw new RuntimeException("Failed to acquire lock: " + lockKey);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted while acquiring lock", e);
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
return result;
}
}</r></r>
使用示例:泛型自动推导,类型安全
调用时无需显式声明泛型,JVM 自动推导:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
DistributedLockTemplate lockTemplate = new DistributedLockTemplate(redissonClient);
// 返回 String
String value = lockTemplate.withLock("order:1001", 30, TimeUnit.SECONDS, () -> {
// 检查库存、扣减、生成订单...
return "order_20240501_123";
});
// 返回 Integer
Integer count = lockTemplate.withLock("counter:pageview", 10, TimeUnit.SECONDS, () -> {
return updateAndReturnCount();
});
每个调用都独立类型,编译期检查,避免 Object 强转或 ClassCastException。
进阶:支持可选超时等待 + 自定义锁名生成器
如果需要更灵活控制(比如尝试获取锁最多等 3 秒),可扩展参数:
public <r> R withLock(String lockKey, long waitTime, long leaseTime,
TimeUnit unit, LockExecutor<r> executor)</r></r>
还可把 lockKey 抽成函数式接口,支持动态生成:
public <r k> R withLock(Supplier<k> keySupplier, ...)</k></r>
例如:() -> "inventory:" + skuId,进一步解耦 key 构造逻辑。
不复杂但容易忽略的是锁 key 的唯一性与业务语义对齐——泛型解决的是类型复用,而正确设计 key 才真正决定锁是否生效。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










