问题产生:分布式环境下,synchronized同步锁是控制不住并发的

官方文档:https://github.com/redisson/redisson

原理分析:https://github.com/redisson/redisson/wiki/8.-%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E5%92%8C%E5%90%8C%E6%AD%A5%E5%99%A8

使用:

一、导入依赖

<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson</artifactId>
  <version>2.7.0</version>
</dependency>
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>

二、配置文件即redis配置

spring:
  application:
    name: server-provider # 指定服务名称为 server-provider
  redis:
    open: true  # 是否开启redis缓存  true开启   false关闭
    database: 10
    host: 127.0.0.1
    port: 6379
    password:   # 密码(默认为空)
    timeout: 6000  # 连接超时时长(毫秒)
    jedis:
      pool:
        max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
        max-wait: -1ms   # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-idle: 10     # 连接池中的最大空闲连接
        min-idle: 5      # 连接池中的最小空闲连接

三、Redisson配置

/**
 * @author chenqi
 * @date 2019/7/15 9:47
 */
public class RedissonManager {
    private static Config config = new Config();
    //声明redisso对象
    private static Redisson redisson = null;
    //实例化redisson
    static {
        //可以用"redis://"来启用SSL连接
        config.useSingleServer().setAddress("127.0.0.1:6379");
        //得到redisson对象
        redisson = (Redisson) Redisson.create(config);
    }
    //获取redisson对象的方法
    public static Redisson getRedisson() {
        return redisson;
    }
}

四、工具类

/**
 * @author chenqi
 * @date 2019/7/15 11:03
 */
public class DistributedRedisLock {
    //从配置类中获取redisson对象
    private static Redisson redisson = RedissonManager.getRedisson();
    private static final String LOCK_TITLE = "redisLock_";
    //加锁
    public static boolean acquire(String lockName){
        //声明key对象
        String key = LOCK_TITLE + lockName;
        //获取锁对象
        RLock mylock = redisson.getLock(key);
        //加锁,并且设置锁过期时间,防止死锁的产生 
        mylock.lock(2, TimeUnit.MINUTES); // 分钟
        System.err.println("======lock======"+Thread.currentThread().getName());
        //加锁成功
        return  true;
    }
    //锁的释放
    public static void release(String lockName){
        //必须是和加锁时的同一个key
        String key = LOCK_TITLE + lockName;
        //获取所对象
        RLock mylock = redisson.getLock(key);
        //释放锁(解锁)
        mylock.unlock();
        System.err.println("======unlock======"+Thread.currentThread().getName());
    }
}

五、测试类一

@RequestMapping("redis2")
public String redis2() throws InterruptedException {
    String key = "test123";
    //加锁
    DistributedRedisLock.acquire(key);
    System.out.println("provider------1-----");
    Thread.sleep(50000);
    System.out.println("provider--1----修改了库");
    //释放锁
    DistributedRedisLock.release(key);
    System.out.println(new Date().getTime());
    return "1111111111";
}

六、测试类二

@RequestMapping("redis2")
public String redis2() {
    String key = "test123";
    //加锁
    DistributedRedisLock.acquire(key);
    System.out.println(new Date().getTime());
    System.out.println("provider------2-----");
    System.out.println("provider--2----修改了库");
    //释放锁
    DistributedRedisLock.release(key);
    return "22222222222";
}

七、结果

我在两个cloud项目,通过zuul网关随机调用两个测试类测试分布式锁,是能够控制住的,测试一,线程睡眠5分钟,再来请求到测试二,但是没执行方法,而是等到测试一过了超时时间2分钟后自动释放了锁,测试二的代码才开始执行,符合预期效果。

Last modification:July 26th, 2019 at 08:33 pm