pom.xml
<!--springboot操作redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
yml
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://127.0.0.1:3306/contact_items?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: zjk1909.
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: ruoyi
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
redis:
database: 0
host: 127.0.0.1
port: 6379
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
timeout: 0
cache:
redis:
time-to-live: 360000000
工具类
package com.ruoyi.web.controller.redislock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
/**
* 分布式同步锁工具类
* @author Administrator
*
*/
@Service
public class SynchrolockUtil {
@Autowired
private RedisTemplate redisTemplate;
/**
* 公共锁key
*/
private static final String LOCK_KEY = "lock";
private static final String VALUE = "isLock";
//通过key值判断做分布式锁 不安全 存在风险
public void redisLockTest(String thredName){
//获取锁,设置有效期,防止程序异常没有释放锁导致死锁
try {
//轮循处理 等待获取锁
while (true)
{
// Boolean b = redisTemplate.opsForValue().setIfAbsent("lock", "value", 3, TimeUnit.MINUTES);
Object isLock = redisTemplate.opsForValue().get(LOCK_KEY);//获取锁
System.out.println(thredName + ": 尝试获取锁");
if (null == isLock){
redisTemplate.opsForValue().set(LOCK_KEY,VALUE);//创建锁
System.out.println(thredName + ":锁创建成功!");
//获取锁成功
//执行业务逻辑
//存储 到redis list 里面
//处理完业务逻辑
break;
}
}
}finally {
//释放锁
redisTemplate.delete(LOCK_KEY);
System.out.println(thredName + ":锁删除成功!!");
}
}
//分布式锁方法
public void redisLockTestTwo(String thredName){
//获取锁,设置有效期,防止程序异常没有释放锁导致死锁
try {
//轮循处理 等待获取锁
while (true)
{
Boolean b = redisTemplate.opsForValue().setIfAbsent(LOCK_KEY, VALUE, Duration.ofSeconds(3));
System.out.println(thredName + ": 尝试获取锁");
if (b){
//获取锁成功
//执行业务逻辑
//存储 到redis list 里面
System.out.println(thredName + ":获取锁成功!");
//处理完业务逻辑
break;
}
}
}finally {
//释放锁
redisTemplate.delete(LOCK_KEY);
System.out.println(thredName + ":锁删除成功!!");
}
}
}
配置类
package com.ruoyi.web.controller.redislock;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
//重新注入RedisTemplate,重新注入会覆盖掉Spring默认提供的
@Bean
public RedisTemplate<String,Object> getRedisTemplate(RedisConnectionFactory factoryBean){
System.out.println("自定义的RedisTemplate被初始化了");
RedisTemplate redisTemplate = new RedisTemplate();
System.out.println("真正使用的factoryBean:"+factoryBean.toString());
redisTemplate.setConnectionFactory(factoryBean);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//自定义redisTemplate必须执行该方法
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
测试方法
package com.ruoyi.web.controller.redislock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/lockTest")
public class LockTest {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private SynchrolockUtil synchrolockUtil;
//分布式锁测试接口
@GetMapping("/test")
public void test() {
Thread thread1 = new Thread(()->{
synchrolockUtil.redisLockTestTwo("线程1");
});
Thread thread2 = new Thread(()->{
synchrolockUtil.redisLockTestTwo("线程2");
});
Thread thread3 = new Thread(()->{
synchrolockUtil.redisLockTestTwo("线程3");
});
//同时启动线程
thread1.start();
thread2.start();
thread3.start();
}
//redis链接测试
@GetMapping("/testRedis")
public void testRedis(){
redisTemplate.opsForValue().set("num","123");
String msg=String.valueOf(redisTemplate.opsForValue().get("num"));
System.out.println(msg);
}
}