全网最简单粘贴即用redisson分布式锁实现

导入redisson

maven

<!--redisson客户端-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.10.2</version>
        </dependency>

gradle

compile group: 'org.redisson', name: 'redisson', version: '3.12.2'

application

spring:
  application:
  redis:
    host: 127.0.0.1
    port: 6379
    database: 16
    password: 123
    lettuce:
      pool:
        #连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池中的最小空闲连接
        min-idle: 0
    timeout: 10000

config

@Configuration
public class RedissonConfig {

    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private Integer port;
    @Value("${spring.redis.database}")
    private Integer database;
    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.redis.timeout}")
    private Integer timeout;
    @Value("${spring.redis.lettuce.pool.max-active}")
    private Integer maxTotal;
    @Value("${spring.redis.lettuce.pool.max-wait}")
    private Integer maxWait;
    @Value("${spring.redis.lettuce.pool.max-idle}")
    private Integer maxIdle;
    @Value("${spring.redis.lettuce.pool.min-idle}")
    private Integer minIdle;

    /**
     * 单机模式自动装配
     *
     * @return
     */
    @Bean
    RedissonClient redissonSingle() {
        Config config = new Config();
        SingleServerConfig serverConfig = config.useSingleServer()
                .setAddress("redis://" + host + ":" + port)
                .setTimeout(timeout)
                .setDatabase(database)
                .setConnectionPoolSize(maxTotal)
                .setConnectionMinimumIdleSize(minIdle);
        if (StringUtils.isNotBlank(password)) {
            serverConfig.setPassword(password);
        }
        return Redisson.create(config);
    }

}

service

public interface RedissonLocker {

    /**
     * 加锁
     *
     * @param lockKey
     * @return
     */
    RLock lock(String lockKey);

    /**
     * 带超时的锁
     *
     * @param lockKey
     * @param timeout 超时时间   单位:秒
     */
    RLock lock(String lockKey, int timeout);

    /**
     * 带超时的锁
     *
     * @param lockKey
     * @param unit    时间单位
     * @param timeout 超时时间
     */
    RLock lock(String lockKey, TimeUnit unit, int timeout);

    /**
     * 释放锁
     *
     * @param lockKey
     */
    void unlock(String lockKey);

    /**
     * 释放锁
     *
     * @param lock
     */
    void unlock(RLock lock);

    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @param waitTime  最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    boolean tryLock(String lockKey, int waitTime, int leaseTime);

    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @param unit      时间单位
     * @param waitTime  最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime);

Impl

@Slf4j
@Component
public class RedissonLockerImple implements RedissonLocker {

    @Autowired
    private RedissonClient redissonClient;

    //默认超时时间 5秒
    private static final int expireTime = 5;

    //默认时间类型 秒
    private static final TimeUnit timeType = TimeUnit.SECONDS;

    //---------------------------------------重入锁(Reentrant Lock)---------------------------------------------------------------

    /**
     * 加锁 lock() 方法尝试获取锁,如果成功获得锁,则继续往下执行,
     * 否则等待锁被释放,然后再继续尝试获取锁,直到成功获得锁。
     * 拿不到lock就不罢休,不然线程就一直block
     * @param lockKey 锁的名称
     * @return
     */
    @Override
    public RLock lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(expireTime, timeType);
        return lock;
    }

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

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

    /**
     * 尝试获取锁 马上返回,拿到lock就返回true,不然返回false。
     * 该方法的使用需要注意(小心)
     * 在业务逻辑做操作 if(tryLock(lockKey, waitTime, leaseTime)){执行具体逻辑}else{不再执行}
     * @param lockKey
     * @param waitTime  最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    @Override
    public boolean tryLock(String lockKey, int waitTime, int leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, timeType);
        } catch (Exception e) {
            log.error("分布式锁尝试获取失败tryLock:", ExceptionUtils.getStackTrace(e));
            return false;
        }
    }

    /**
     * 尝试获取锁 该方法的使用需要注意(小心)
     * 在业务逻辑做操作 if(tryLock(lockKey, waitTime, leaseTime)){执行具体逻辑}else{不再执行}
     *
     * @param lockKey
     * @param unit      时间单位
     * @param waitTime  最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    @Override
    public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (Exception e) {
            log.error("分布式锁尝试获取失败tryLock:{}", ExceptionUtils.getStackTrace(e));
            return false;
        }
    }

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

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


    //--------------------------------以下不建议使用-除非理解透彻--------------------------------------------------

    /**
     * 分布式锁的异步执行 解锁 unlockAsync(key)
     * 在业务逻辑做操作 if(asyncReentrantLock(lockKey, waitTime, leaseTime)){执行具体逻辑}else{不再执行}
     *
     * @param lockKey
     * @param waitTime  最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     */
    public Boolean asyncReentrantLock(String lockKey, int waitTime, int leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        Boolean res = false;
        try {
            Future<Boolean> result = lock.tryLockAsync(waitTime, leaseTime, timeType);
            res = result.get();
        } catch (Exception e) {
            log.error("分布式锁异步执行失败asyncReentrantLock:{}", ExceptionUtils.getStackTrace(e));
        }
        return res;
    }

    /**
     * 公平锁
     * 当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。
     *
     * @param lockKey
     * @param leaseTime
     */
    public boolean fairLock(String lockKey, int waitTime, int leaseTime) {
        RLock fairLock = redissonClient.getFairLock(lockKey);
        try {
            //该方法没有返回值,一定会加锁
            //fairLock.lock(leaseTime,timeType);
            //该方法需要 判断锁的持有情况
            return fairLock.tryLock(waitTime, leaseTime, timeType);
        } catch (Exception e) {
            log.error("分布式锁公平锁失败asyncReentrantLock:{}", ExceptionUtils.getStackTrace(e));
            return false;
        }
    }

    /**
     * 公平锁 的异步执行
     * 保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。
     *
     * @param lockKey
     * @param leaseTime
     */
    public boolean fairAsyncLock(String lockKey, int waitTime, int leaseTime) {
        RLock fairLock = redissonClient.getFairLock(lockKey);
        Boolean res = false;
        try {
            Future<Boolean> result = fairLock.tryLockAsync(waitTime, leaseTime, timeType);
            res = result.get();
        } catch (Exception e) {
            log.error("公平锁 的异步执行失败asyncReentrantLock:{}", ExceptionUtils.getStackTrace(e));
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值