两行代码 完成分布式锁

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35704236/article/details/80634332

springboot + lombock + redission 实现分布式

1 缘起

由于工作中需要用到分布式锁,在查看很多博客以后,发现很多博客都是错误的,于是就完成了 《Java 正确实现 redis 分布式锁》(下面有链接) ,但是心中一直不大满意,直到我发现了 redission, 爱折腾的我有了下面的故事。。。


  • 通过 jedis 实现的分布式锁, 参照之前的文章

Java 正确实现 redis 分布式锁 https://blog.csdn.net/qq_35704236/article/details/80406916

2 效果

技术服务业务,当然是越简单越好

RedissLockUtil.lock("ORDER_123456");

// TODO 业务逻辑

RedissLockUtil.unlock("ORDER_123456");

3 实现

3.1 二话不说,直接导包


<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.5.0</version>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.18</version>
    <scope>provided</scope>
</dependency>

3.2 RedissonProperties rediss配置类

package com.study.redission;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * rediss 配置类 请根据实际情况调整
 */
@Data
@ConfigurationProperties(prefix = "redisson")
public class RedissonProperties {

    /**
     * Redis服务器响应超时
     */
    private int timeout = 3000;

    private String address;

    private String password;

    private int connectionPoolSize = 64;

    private int connectionMinimumIdleSize = 10;

    private int slaveConnectionPoolSize = 250;

    private int masterConnectionPoolSize = 250;

    private String[] sentinelAddresses;

    private String masterName;
}

3.3 RedisstionConfig

package com.study.redission;

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.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author: huangwenjun
 * @Description:
 * @Date: Created in 18:09  2018/6/8
 **/
@Configuration
@EnableConfigurationProperties(RedissonProperties.class)
public class RedisstionConfig {

    @Autowired
    private RedissonProperties redssionProperties;

    /**
     * 单机模式自动装配
     * @return
     */
    @Bean
    RedissonClient redissonSingle() {
        Config config = new Config();
        SingleServerConfig serverConfig = config.useSingleServer()
                .setAddress(redssionProperties.getAddress())
                .setTimeout(redssionProperties.getTimeout())
                .setConnectionPoolSize(redssionProperties.getConnectionPoolSize())
                .setConnectionMinimumIdleSize(redssionProperties.getConnectionMinimumIdleSize());

        if(redssionProperties.getPassword() != null && !"".equals(redssionProperties.getPassword().trim())) {
            serverConfig.setPassword(redssionProperties.getPassword());
        }

        RedissonClient redissonClient = Redisson.create(config);
        // 将client注入
        RedissLockUtil.setLocker(redissonClient);

        return redissonClient;
    }
}

3.4 RedissLockUtil 分布式锁工具类

package com.study.redission;

import java.util.concurrent.TimeUnit;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;


/**
 * @Author: huangwenjun
 * @Description:
 * @Date: Created in 18:15  2018/6/8
 **/
public class RedissLockUtil {

    private static RedissonClient redissonClient;

    protected static void setLocker(RedissonClient locker) {
        redissonClient = locker;
    }

    /**
     * 加锁
     * @param lockKey
     * @return
     */
    public static RLock lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();

        return lock;
    }

    /**
     * 释放锁
     * @param lockKey
     */
    public static void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }

    /**
     * 释放锁
     * @param lock
     */
    public static void unlock(RLock lock) {
        lock.unlock();
    }

    /**
     * 带超时的锁
     * @param lockKey
     * @param timeout 超时时间   单位:秒
     */
    public static RLock lock(String lockKey, int timeout) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, TimeUnit.SECONDS);
        return lock;
    }

    /**
     * 带超时的锁
     * @param lockKey
     * @param unit 时间单位
     * @param timeout 超时时间
     */
    public static RLock lock(String lockKey, TimeUnit unit ,int timeout) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, unit);
        return lock;
    }

    /**
     * 尝试获取锁
     * @param lockKey
     * @param unit 时间单位
     * @param waitTime 最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
            return false;
        }
    }
}

3.5 配置

redisson.address=redis://127.0.0.1:6379
redisson.password=

4 好的代码一定要有测试

4.1 测试代码

@RequestMapping("lock")
public void lock() {
    System.out.println(Thread.currentThread().getName() + ",抢占锁");

    RedissLockUtil.lock("ORDER_123456");
    System.out.println(Thread.currentThread().getName() + ", 获取锁");

    // TODO 业务逻辑
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    RedissLockUtil.unlock("ORDER_123456");
    System.out.println(Thread.currentThread().getName() + ", 释放锁");
}

4.2 输出

http-nio-8080-exec-1,抢占锁
http-nio-8080-exec-1, 获取锁
http-nio-8080-exec-5,抢占锁
http-nio-8080-exec-1, 释放锁
http-nio-8080-exec-5, 获取锁
http-nio-8080-exec-2,抢占锁
http-nio-8080-exec-5, 释放锁
http-nio-8080-exec-2, 获取锁
http-nio-8080-exec-2, 释放锁

5 进阶修炼

当然身为高手的你肯定你仅仅满足与此, 下面安利一下 redisson 的官网

https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95

6 结束

搞完收工,如果你喜欢博主的文章的话麻烦点一下关注,如果发现博主文章的错误的话 麻烦指出, 谢谢大家。

ref:

https://www.cnblogs.com/yangzhilong/p/7605807.html

扫描二维码关注公众号,回复: 4130855 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_35704236/article/details/80634332