1.RedissonConfig配置
package com.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author
* 2021/3/24 17:14
*/
@Slf4j
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private String port;
@Value("${spring.redis.database}")
private Integer db;
@Value("${spring.redis.password}")
private String passWord;
@Bean(destroyMethod = "shutdown")
public RedissonClient redissonClient() {
Config config = new Config();
// 监控锁的看门狗超时(默认30秒),单位:毫秒
config.setLockWatchdogTimeout(60000);
SingleServerConfig singleServerConfig =
config
// 单机环境, 集群环境(useClusterServers())
.useSingleServer()
.setAddress(
String.format( "redis://"+host+":"+port)
)
.setDatabase(db);
if (StringUtils.isNotEmpty(passWord)) {
singleServerConfig.setPassword(passWord);
}
return Redisson.create(config);
}
}
2.分布式锁实现
package com.*
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
/**
* @author
* 2021/3/24 17:34
*/
public interface DistributedLocker {
/**
* 锁名称前缀
*/
String LOCK_KEY_PREFIX_KEY = "distributed:keys:";
/**
* 可重入锁
*
* @param key 锁名称
* @return 锁对象
*/
RLock lock(String key);
/**
* 公平锁
*
* @param key 锁名称
* @return 锁对象
*/
RLock fairLock(String key);
<T> T fairLock(String key, Supplier<T> supplier);
/**
* 读写锁
*
* @param key 锁名称
* @return 锁对象
*/
RReadWriteLock readWriteLock(String key);
/**
* 在锁内执行业务
*
* @param key 锁名称
* @param supplier 具体业务逻辑
* @param <T>
* @return 操作结果
*/
<T> T lock(String key, Supplier<T> supplier);
/**
* 可重入锁(设置锁的持有时间)
*
* @param key 锁名称
* @param leaseTime 上锁后, leaseTime 后自动解锁
* @param unit 单位
* @param supplier 业务执行结果
* @param <T>
* @return 锁对象
*/
<T> T lock(String key, int leaseTime, TimeUnit unit, Supplier<T> supplier);
/**
* 尝试获取锁
*
* @param key 锁名称
* @param supplier 具体业务逻辑
* @param <T>
* @return 业务执行结果
*/
<T> T tryLock(String key, Supplier<T> supplier);
/**
* 尝试获取锁(为加锁等待 waitTime unit时间)
*
* @param key 锁名称
* @param waitTime 获取锁最长等待时间
* @param unit 单位
* @param supplier 具体业务逻辑
* @param <T>
* @return 业务执行结果
* @throws InterruptedException ex
*/
<T> T tryLock(String key, long waitTime, TimeUnit unit, Supplier<T> supplier)
throws InterruptedException;
/**
* 尝试获取锁(为加锁等待 waitTime unit时间,并在加锁成功 leaseTime unit 后自动解开)
*
* @param key 锁名称
* @param waitTime 获取锁最长等待时间
* @param leaseTime 上锁后, leaseTime 后自动解锁
* @param unit 单位
* @param supplier 具体业务逻辑
* @param <T>
* @return 业务执行结果
* @throws InterruptedException ex
*/
<T> T trysLock(String key, long waitTime, int leaseTime, TimeUnit unit, Supplier<T> supplier)
throws InterruptedException;
/**
* 解锁
*
* @param lock 锁对象
*/
default void unlock(RLock lock) {
if (lock != null && lock.isLocked()) {
lock.unlock();
}
}
<T> T multiLock(String[] keys, Supplier<T> supplier);
}
package com.*
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
/**
* @author
* 2021/3/24 17:34
*/
@Component
public class RedissonLocker implements DistributedLocker {
@Autowired
private RedissonClient redissonClient;
@Override
public RLock lock(String key) {
return redissonClient.getLock(key);
}
@Override
public RLock fairLock(String key) {
return redissonClient.getFairLock(key);
}
@Override
public <T> T fairLock(String key, Supplier<T> supplier) {
RLock lock = fairLock(key);
try {
lock.lock();
return supplier.get();
} finally {
if (lock != null && lock.isLocked()) {
lock.unlock();
}
}
}
@Override
public RReadWriteLock readWriteLock(String key) {
return redissonClient.getReadWriteLock(key);
}
@Override
public <T> T lock(String key, Supplier<T> supplier) {
RLock lock = lock(key);
try {
lock.lock();
return supplier.get();
} finally {
if (lock != null && lock.isLocked()) {
lock.unlock();
}
}
}
@Override
public <T> T lock(String key, int leaseTime, TimeUnit unit, Supplier<T> supplier) {
RLock lock = this.lock(key);
try {
lock.lock(leaseTime, unit);
return supplier.get();
} finally {
unlock(lock);
}
}
@Override
public <T> T tryLock(String key, Supplier<T> supplier) {
RLock lock = this.lock(key);
boolean tryLock = false;
try {
tryLock = lock.tryLock();
if (tryLock) {
return supplier.get();
}
} finally {
if (tryLock) {
unlock(lock);
}
}
return null;
}
@Override
public <T> T tryLock(String key, long waitTime, TimeUnit unit, Supplier<T> supplier)
throws InterruptedException {
RLock lock = this.lock(key);
boolean tryLock = false;
try {
tryLock = lock.tryLock(waitTime, unit);
if (tryLock) {
return supplier.get();
}
} finally {
if (tryLock) {
unlock(lock);
}
}
return null;
}
@Override
public <T> T trysLock(String key, long waitTime, int leaseTime, TimeUnit unit, Supplier<T> supplier)
throws InterruptedException {
RLock lock = this.lock(key);
boolean tryLock = false;
try {
tryLock = lock.tryLock(waitTime, leaseTime, unit);
if (tryLock) {
return supplier.get();
}
} finally {
if (tryLock) {
unlock(lock);
}
}
return null;
}
@Override
public void unlock(RLock lock) {
DistributedLocker.super.unlock(lock);
}
@Override
public <T> T multiLock(String[] keys, Supplier<T> supplier) {
return null;
}
}
3.引入相关依赖包
<dependency>
<groupId>com.zhongan</groupId>
<artifactId>za-aliyun-redis-client</artifactId>
<version>0.0.9</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.3</version>
</dependency>