基于设计模式,实现分布式锁的资源管理

org.redisson.api.RLock,是目前较为常见的分部署锁实现方式。我们的目的是实现自动管理锁的获取和释放。

但遗憾的是,RLock并不实现AutoCloseable接口,因此不能直接用在try-with-resources结构中。不过,我们可以通过创建一个包装类或者辅助方法,使得RLock的使用更加符合try-with-resources模式。这样做的好处是使得代码更加简洁,并且能够保证即使发生异常也能够正确释放资源。

1.实现代码

1.1包装类

复制代码
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import java.util.concurrent.TimeUnit;
/**
 * @Description: RLock并不实现AutoCloseable接口,因此不能直接用在try-with-resources结构中。
 * 创建一个包装类,使得RLock的使用更加符合try-with-resources模式。这样做的好处是使得代码更加简洁,并且能够保证即使发生异常也能够正确释放资源
 **/
@Slf4j
public class AutoCloseableLock implements AutoCloseable{

	/**
	 * 锁定请求
	 */
	private final String target;

	/**
	 * 要获取的锁。
	 */
	private final RLock lock;

	/**
	 *锁状态
	 */
	private final boolean locked;

	/**
	 * 获取锁的等待时长
	 */
	private static final int WAIT_TIME = 3;

	/**
	 * 占用锁的最大时长
	 */
	private static final int LEASE_TIME = 10;

	public AutoCloseableLock(RLock lock, String target) throws InterruptedException {
		this.lock = lock;
		// 尝试获取锁,并立即返回结果。如果获取成功,设置锁的自动释放时间。
		this.locked = lock.tryLock(WAIT_TIME,LEASE_TIME, TimeUnit.SECONDS);
		this.target = target;
	}

	public boolean isLocked() {
		log.info("=====redisson分布式锁,【{}】上锁成功=====",this.target);
		return this.locked;
	}

	@Override
	public void close() {
		if (this.locked && lock.isHeldByCurrentThread()) {
			log.info("=====redisson分布式锁,【{}】开锁成功=====",this.target);
			lock.unlock();
		}
	}
}

1.2参数枚举类

复制代码
public enum LockEnum {
	login("LOGIN", "用户登录请求");

	/**
	 * 锁前缀
	 */
	private final String prefix;

	/**
	 * 锁请求
	 */
	private final String target;

	LockEnum(String prefix, String target) {
		this.prefix = prefix;
		this.target = target;
	}

	public String getPrefix() {
		return prefix;
	}

	public String getTarget() {
		return target;
	}
}

1.3 类的使用

复制代码
try (AutoCloseableLock autoLock = new AutoCloseableLock(
				redissonClient.getLock(StrUtil.format("{}_{}", LockEnum.login.getPrefix(), username)),
				LockEnum.login.getTarget())) {
    if (autoLock.isLocked()) {
        // 成功获取锁,执行业务逻辑...
    } else {
        // 获取锁失败的处理逻辑...
    }
} catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // 重新设置中断状态
    // 处理中断异常...
}

2设计模式讲解

在这个示例中,AutoCloseableLock包装了一个Lock对象,并确保了在try-with-resources语句结束时自动释放锁,这既体现了资源管理器模式的优势,也借助装饰器模式的理念,为Lock对象增加了自动资源管理的功能。

2.1 资源管理器(Resource Management)模式

资源管理器设计模式的核心思想是确保对于需要手动管理的资源(如文件、数据库连接或锁等),在使用完毕后能够自动释放,以避免资源泄漏。在Java中,try-with-resources语句是这一模式的一个体现,它要求资源实现AutoCloseable或Closeable接口。当try块执行完毕时,无论是正常完成还是因为异常退出,都会自动调用close()方法来释放资源。

AutoCloseableLock类通过实现AutoCloseable接口,使得锁资源可以在try-with-resources语句中自动管理,从而简化了锁的获取和释放过程,减少了编码错误导致的资源泄漏风险。

2.2 装饰器(Decorator)模式

装饰器设计模式允许向一个对象添加新的功能,而不改变其结构。这是通过创建一个包含了原始对象的新对象来实现的,即"装饰"了原始对象。在AutoCloseableLock的上下文中,虽然它的主要目的不是为了添加新功能,但它通过包装Lock对象,并在此基础上添加了自动资源管理的功能,从某种角度来看,也体现了装饰器模式的思想。

相关推荐
哈哈哈笑什么12 分钟前
分布式高并发Springcloud系统下的数据图同步断点续传方案【订单/商品/用户等】
分布式·后端·spring cloud
LDG_AGI19 分钟前
【推荐系统】深度学习训练框架(十三):模型输入——《特征索引》与《特征向量》的边界
人工智能·pytorch·分布式·深度学习·算法·机器学习
回家路上绕了弯1 小时前
多线程开发最佳实践:从安全到高效的进阶指南
分布式·后端
少许极端2 小时前
Redis入门指南:从零到分布式缓存(一)
redis·分布式·缓存·微服务
爬山算法2 小时前
Redis(161)如何使用Redis实现分布式锁?
数据库·redis·分布式
边缘计算社区3 小时前
云边协同推理再突破:新型分布式解码框架吞吐量提升近 10%
分布式
大猫子的技术日记3 小时前
[后端杂货铺]深入理解分布式事务与锁:从隔离级别到传播行为
分布式·后端·事务
繁华似锦respect6 小时前
HTTPS 中 TLS 协议详细过程 + 数字证书/签名深度解析
开发语言·c++·网络协议·http·单例模式·设计模式·https
小股虫6 小时前
分布式一致性算法深度解析:Paxos、Raft与ZAB的原理、实现与应用
分布式
数智研发说6 小时前
智汇电器携手鼎捷PLM:从“制造”迈向“智造”,构建高效协同研发新范式
大数据·人工智能·设计模式·重构·制造·设计规范