在前面的文章《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获取分布式锁的相关示例方案,最后按照惯例,附上本案例的源码,登录后即可下载。












还没有评论,来说两句吧...