package com.redis;/*** @author linn* @date 2024年04月23日 15:31*/
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RedissonConfig {@Bean(destroyMethod="shutdown")public RedissonClient redissonClient() {Config config = new Config();config.setLockWatchdogTimeout(2000);config.setNettyThreads(5);config.setKeepPubSubOrder(true);config.setMaxCleanUpDelay(2000);config.setMinCleanUpDelay(200);config.setThreads(5);config.useSingleServer().setAddress("redis://127.0.0.1:6379");return Redisson.create(config);}
}
RedissonConfig配置类如上:
以下是测试类:
package com.redis;/*** @author linn* @date 2024年04月23日 16:09*/
import com.DemoApplication;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;/*** @ClassName RedissonTest* @Description Redisson测试用例* @Author 阿Q* @Date 2022/11/26*/
@Slf4j
@SpringBootTest(classes = DemoApplication.class)
public class RedissonTest {@Resourceprivate RedissonClient redissonClient;@Resourceprivate ThreadPoolTaskExecutor executor;// redisson分布式锁的keyprivate static final String LOCK_TEST_KEY = "redisson:lock:test";private static final String LOCK_TITLE = "redisLock_";int n = 500;/*** 分布式锁测试用例*/@Testpublic void lockTest() {// 利用 循环+多线程 模仿高并发请求for (int i = 0; i < 10; i++) {executor.execute(() -> {// 这里获取公平锁,遵循先进先出原则,方便测试RLock fairLock = redissonClient.getFairLock(LOCK_TEST_KEY);try {// 尝试加锁// waitTimeout 尝试获取锁的最大等待时间,超过这个值,则认为获取锁失败// leaseTime 锁的持有时间,超过这个时间锁会自动失效(值应设置为大于业务处理的时间,确保在锁有效期内业务能处理完)boolean lock = fairLock.tryLock(3000, 30, TimeUnit.MILLISECONDS);if (lock){log.info("线程:" + Thread.currentThread().getName() + "获得了锁");log.info("剩余数量:{}", --n);}} catch (InterruptedException e) {e.printStackTrace();} finally {log.info("线程:" + Thread.currentThread().getName() + "准备释放锁");// 注意,无论出现任何情况,都要主动解锁fairLock.unlock();}});}try {// ->_-> 这里使当前方法占用的线程休息10秒,不要立即结束Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}//加锁public boolean acquire(String lockName) {//声明key对象String key = LOCK_TITLE + lockName;//获取锁对象RLock mylock = redissonClient.getLock(key);//加锁,并且设置锁过期时间3秒,防止死锁的产生 uuid+threadIdmylock.lock();boolean flag = mylock.isLocked();//加锁成功return true;}//锁的释放public void release(String lockName) {//必须是和加锁时的同一个keyString key = LOCK_TITLE + lockName;//获取所对象RLock mylock = redissonClient.getLock(key);//释放锁(解锁)mylock.unlock();System.out.println("释放锁成功!"+key);}@Testpublic void releaseTest(){acquire("test_lock");release("test_lock");}
}
properties的配置类:
redisson.config=classpath:redisson.yaml
redisson.yaml配置类如下:
# 单一 Redis 服务器模式
singleServerConfig:# Redis 服务器的地址address: "redis://127.0.0.1:6379"# 连接池的大小connectionPoolSize: 64# Redis 服务器的密码password:# Redis 数据库索引database: 0# 客户端名称clientName:# 超时时间,单位为毫秒timeout: 3000# Redis 命令失败重试次数retryAttempts: 3# 两次命令之间重试的时间间隔,单位为毫秒retryInterval: 1500# 发布和订阅的连接的最小数量subscriptionConnectionMinimumIdleSize: 1# 发布和订阅的连接池的大小subscriptionConnectionPoolSize: 50# 当前处理 Redis 命令的线程共享的联接connectionMinimumIdleSize: 10# 集群模式的配置 (需要注释或删除 singleServerConfig 当使用此模式)
#clusterServersConfig:
# scanInterval: 2000
# slaveConnectionPoolSize: 64
# slaveConnectionMinimumIdleSize: 24
# masterConnectionPoolSize: 64
# masterConnectionMinimumIdleSize: 24
# readMode: "SLAVE"
# nodeAddresses:
# - "redis://127.0.0.1:7001"
# - "redis://127.0.0.1:7002"
# - "redis://127.0.0.1:7003"
# password: "your_password"# 其他模式,如 sentinel, masterSlave, replicated 可以在这里配置,但确保只有一个模式处于未注释状态# 线程工厂配置
threads: 16
nettyThreads: 32# 编解码器配置,默认是 Jackson
codec: !<org.redisson.codec.JsonJacksonCodec> {}# 传输模式,默认是 NIO
transportMode: "NIO"
pom.xml配置文件:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.10.5</version></dependency>
应用到自己项目中的截图如下:
finally释放锁:
redisson加的锁和普通redis.setnx不同,数据结构不同: