在前面的文章《Spring Cloud微服务项目模板系列(九)redisTemplate集成分布式锁》,但是大家说到redis分布式锁,一般都会想到使用redisson分布式锁。所以本文我们做一个Redisson分布式锁的框架。下面直接开始
1)首先创建一个maven项目,并且引入相关的依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.spring.redis.redisson</groupId> <artifactId>spring-redisson</artifactId> <version>1.0</version> <packaging>jar</packaging> <name>spring-redisson</name> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.5</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <spring-boot.version>2.7.5</spring-boot.version> <redisson.version>3.16.3</redisson.version> <hutool.version>5.4.0</hutool.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>${redisson.version}</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>${hutool.version}</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
2)定义一个分布式锁的接口
这里我们定义一个分布式锁的接口,后期直接实现即可,示例代码如下:
package com.spring.redis.redisson.lock; import java.util.concurrent.TimeUnit; /** * 分布式锁的接口 * @author Administrator * */ public interface DistributedLock { boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException; boolean tryLock(long waitTime, TimeUnit unit) throws InterruptedException; boolean tryLock() throws InterruptedException; void lock(long leaseTime, TimeUnit unit); void unlock(); boolean isLocked(); boolean isHeldByThread(long threadId); boolean isHeldByCurrentThread(); }
3)创建一个分布式锁工厂
这里我们使用工厂模式来使用分布式锁,所以我们定义一个分布式锁的工厂类,示例代码如下:
package com.spring.redis.redisson.lock; /** * * @author Administrator * */ public interface DistributedLockFactory { /** * 根据key获取分布式锁 */ DistributedLock getDistributedLock(String key); }
4)实现分布式锁工厂
然后我们再实现这个分布式锁的工厂,示例代码如下:
package com.spring.redis.redisson.lock.impl; import java.util.concurrent.TimeUnit; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.spring.redis.redisson.lock.DistributedLock; import com.spring.redis.redisson.lock.DistributedLockFactory; /** * 基于Redisson的分布式锁实现 * @author Administrator * */ @Component public class RedissonLockFactory implements DistributedLockFactory { private final Logger logger = LoggerFactory.getLogger(RedissonLockFactory.class); @Autowired private RedissonClient redissonClient; @Override public DistributedLock getDistributedLock(String key) { RLock rLock = redissonClient.getLock(key); return new DistributedLock() { @Override public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException { boolean isLockSuccess = rLock.tryLock(waitTime, leaseTime, unit); logger.info("{} get lock result:{}", key, isLockSuccess); return isLockSuccess; } @Override public boolean tryLock(long waitTime, TimeUnit unit) throws InterruptedException { return rLock.tryLock(waitTime, unit); } @Override public boolean tryLock() throws InterruptedException { return rLock.tryLock(); } @Override public void lock(long leaseTime, TimeUnit unit) { rLock.lock(leaseTime, unit); } @Override public void unlock() { if (isLocked() && isHeldByCurrentThread()) { rLock.unlock(); } } @Override public boolean isLocked() { return rLock.isLocked(); } @Override public boolean isHeldByThread(long threadId) { return rLock.isHeldByThread(threadId); } @Override public boolean isHeldByCurrentThread() { return rLock.isHeldByCurrentThread(); } }; } }
5)配置一个测试类的controller
编写一个测试类的controller,示例代码如下:
package com.spring.redis.redisson.controller; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.spring.redis.redisson.lock.DistributedLock; import com.spring.redis.redisson.lock.DistributedLockFactory; import com.spring.redis.redisson.utils.CalUtils; @RestController public class HelloController { private static final Logger LOGGER = LoggerFactory.getLogger(HelloController.class); // 分布式锁key的后缀 private static final String LOCK_SUFFIX = "_lock"; // 等待锁时间,默认2秒 private static final Long LOCK_WAIT_TIMEOUT = 2000L; @Autowired private DistributedLockFactory distributedLockFactory; @RequestMapping("hello") public String hello() { String key = "uid:1"; // 分布式锁 String lockKey = this.getLockKey(key); // 获取分布式锁 DistributedLock distributedLock = distributedLockFactory.getDistributedLock(lockKey); boolean isLock = false; try { isLock = distributedLock.tryLock(LOCK_WAIT_TIMEOUT, TimeUnit.MILLISECONDS); // 获取锁成功, Double Check if (isLock) { // TODO 做自己准备做的事情 this.doaction(); } else { throw new RuntimeException("没有获取到锁"); } } catch (Exception e) { LOGGER.error(e.getMessage(), e); throw new RuntimeException(e); } finally { if (isLock) { distributedLock.unlock(); } } return "hello"; } @RequestMapping("hello1") public Integer hello1() { return CalUtils.getValue(); } private void doaction() { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } CalUtils.addValue(); } // 分布式锁Key private String getLockKey(String key) { return key.concat(LOCK_SUFFIX); } }
6)测试
首先启动项目,通过hello1接口访问值
可以看到初始值是1,然后我们并发测试下hello接口
可以看到成功了12次,那么我们预期通过hello1接口获取到的值应该是13,我们再请求下hello1接口,看下是否符合预期
没有任何问题。
以上就是使用redisson获取分布式锁的相关示例方案,最后按照惯例,附上本案例的源码,登录后即可下载。
还没有评论,来说两句吧...