Java中函数式接口实现分布式锁
背景
最近使用分布式锁比较多,发现大家使用分布式锁,都各有各的用法,想着用搞一个加锁模板,方便大家使用,就选择声明一个函数式接口,去实现加锁的模板
函数式接口
是一种特殊的接口,只包含一个抽象方法。函数式接口的目的是为了支持函数式编程,使开发者能够以更简洁的方式定义单一抽象方法的接口,从而可以使用Lambda表达式来实现这个接口的抽象方法。可以通过lambda表达式进行传递,简单理解就是java8对函数式编程的一种支持
实战
我们一般加锁是这样,尝试获取锁,失败则抛异常,成功则执行业务代码,每次都要写一大段逻辑
RLock lock = redissonClient.getLock(lockKey);
try {
if (!lock.tryLock(waitTime, leaseTime, unit)) {
throw new CommonException(ErrorCodeEnum.TRY_LOCK_ERROR).detailMessage("操作频繁,请稍后再试!");
}
。。。。业务代码
}catch (CommonException commonException) {
} catch (Exception e) {
log.error("LockTemplate >> 获取锁异常",e);
} finally {
try {
// 锁不为空 是否还是锁定状态 当前执行线程的锁
if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
} catch (Exception e) {
log.error("LockTemplate >> 获取锁异常",e);
}
}
}
所以可以采用函数是接口,定义一套加锁模板,开发者就可以只关注业务代码,而不用去写一大段加锁逻辑,
package com.dept.common.template;
import cn.hutool.core.util.StrUtil;
import com.dept.common.enums.ErrorCodeEnum;
import com.dept.common.exception.CommonException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
@AllArgsConstructor
@Slf4j
public class LockTemplate {
private RedissonClient redissonClient;
public void templateLock(String prefix,String key,Runnable target,long waitTime, long leaseTime, TimeUnit unit) {
String lockKey = StrUtil.format(prefix,key);
// 判断是否正在使用
RLock lock = redissonClient.getLock(lockKey);
try {
if (!lock.tryLock(waitTime, leaseTime, unit)) {
throw new CommonException(ErrorCodeEnum.TRY_LOCK_ERROR).detailMessage("操作频繁,请稍后再试!");
}
// 执行业务代码
target.run();
}catch (CommonException e){
throw e;
} catch (Exception e) {
log.error("LockTemplate >> 获取锁异常",e);
} finally {
try {
// 锁不为空 是否还是锁定状态 当前执行线程的锁
if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
} catch (Exception e) {
log.error("LockTemplate >> 获取锁异常",e);
}
}
}
}
重点就是将Runnable做为入参,Runnable是一个函数式接口,所以我们可以直接传入业务实现,当然我们也可以自己定义一个函数式接口
lockTemplate.templateLock(SystemConstants.STAR_TASK_MINA_ORDER_LOCK, order.getOrderSn(), () -> {
。。。业务实现
}, RedisConstants.ONE_SECOND, RedisConstants.TEN_SECOND, TimeUnit.MINUTES);
这样我们就可以不用去关注加锁逻辑,只需要写自己的业务代码接口
总结
通过函数式接口,我们可以定义很多模板代码,让开发者只需要传入对应的业务实现即可,TransactionTemplate的execute的方法也是类似的实现
到此这篇关于Java中函数式接口实现分布式锁的文章就介绍到这了,更多相关Java 分布式锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
关于Redis键值出现\xac\xed\x00\x05t\x00&错误的解决方法
这篇文章主要介绍了关于Redis键值出现\xac\xed\x00\x05t\x00&的解决方法,出现该问题的原因是, redis template向redis存放使用java对象序列化的值,序列化方式和string的一般方式不同,需要的朋友可以参考下2023-08-08
详解Java设计模式编程中的Flyweight享元模式的开发结构
这篇文章主要介绍了Java设计模式编程中的Flyweight享元模式的开发结构,享元模式能够最大限度地重用现有的同类对象,需要的朋友可以参考下2016-04-04
如何解决Could not transfer artifact org.spri
在Maven更新过程中遇到“Could not transfer artifact org.springframework.boot”错误通常是由于网络问题,解决方法是在Maven的设置中忽略HTTPS,添加特定语句后,可以正常下载依赖,但下载速度可能较慢,这是一种常见的解决方案,希望对遇到相同问题的人有所帮助2024-09-09
最新IntelliJ IDEA 2022配置 Tomcat 8.5 的详细步骤演示
这篇文章主要介绍了IntelliJ IDEA 2022 详细配置 Tomcat 8.5 步骤演示,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2022-08-08
IDEA database和datagrip无法下载驱动问题解决办法
这篇文章主要给大家介绍了关于IDEA database和datagrip无法下载驱动问题的解决办法,文中通过代码介绍的非常详细,对大家学习或者使用idea具有一定的参考借鉴价值,需要的朋友可以参考下2024-03-03


最新评论