springboot 集成 redis分布式锁

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);
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值