redisson看门狗锁及RedissonLockUtil

文章详细描述了如何使用Redisson库在Java中实现分布式锁功能,包括获取、尝试获取、解锁等操作,以及不同方法的参数含义和应用场景。
摘要由CSDN通过智能技术生成
public void updateHordeAdvertClickNum(HordeAdvertInfoRequest request) {
        String lockKey = "HORDE_ADVERT_CLICK_KEY:" + request.getAdvertId();
        RLock rLock = redisson.getLock(lockKey);
        try {
            boolean lock = rLock.tryLock(2L, TimeUnit.SECONDS);
            if (lock) {
                HordeAdvertInfoEntity entity = hordeAdvertInfoMapper.findById(request.getAdvertId());
                MongoUpdateWrapper wrapper = new MongoUpdateWrapper();
                Integer clickNum = entity.getClickNum()==null?0:entity.getClickNum();
                wrapper.set(HordeAdvertInfoEntity::getClickNum, clickNum+1);
                wrapper.and(HordeAdvertInfoEntity::getId).eq(request.getAdvertId());
                hordeAdvertInfoMapper.update(wrapper);
            } else {
                throw BusinessException.newParamsException("获取锁失败!");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            rLock.unlock();
        }
    }



​
public void test() throws Exception{
        RLock lock = redissonClient.getLock("guodong");    // 拿锁失败时会不停的重试
        
        // 具有Watch Dog 自动延期机制 默认续30s 每隔30/3=10 秒续到30s
        lock.lock();
         
        // 具有Watch Dog 自动延期机制 默认续30s
        // 尝试拿锁10s后停止重试,返回false 具有Watch Dog 自动延期机制 默认续30s
        boolean res1 = lock.tryLock(10, TimeUnit.SECONDS); 
       
       // 没有Watch Dog 
       // 尝试获取锁10秒,如果获取不到则放弃
        lock.lock(10, TimeUnit.SECONDS);
       
       // 没有Watch Dog 
       // 尝试获取锁,等待100秒,持有锁10秒钟
        boolean res2 = lock.tryLock(100, 10, TimeUnit.SECONDS);
        
        
        Thread.sleep(40000L);
       
        
        lock.unlock();
    }

​
package com.flhy.redis.utils;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author zengqingyu
 * @Desc: 分布式锁工具类
 */
@Component
@Slf4j
public class RedissonLockUtil {

    @Resource
    private RedissonClient client;


    private final static String SPLIT = "/";

    /**
     * 超时时间15秒(占有锁的最长时间)
     */
    private final static Integer TIMEOUT = 15;


    /**
     * 获取业务锁
     *
     * @param prefix     业务号锁前缀
     * @param businessNo 业务号
     */
    public void lock(String prefix, String businessNo) {
        RLock rLock = client.getLock(prefix + SPLIT + businessNo);
        rLock.lock(TIMEOUT, TimeUnit.SECONDS);
    }

    /**
     * 解锁
     *
     * @param prefix     业务号锁前缀
     * @param businessNo 业务号
     */
    public void unlock(String prefix, String businessNo) {
        RLock rLock = client.getLock(prefix + SPLIT + businessNo);
        try {
            if (rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        } catch (IllegalMonitorStateException e) {
            log.error("RedissonLockUtil lock timeout unlock", e);
        }
    }


    /**
     * 尝试获取分布式锁,带有尝试获取锁的等待时间 和 占有锁之后的释放时间
     *
     * @param prefix     业务号前缀
     * @param businessNo 业务号
     * @param waitTime   这个参数决定了在尝试获取锁时的最长等待时间。当你的程序尝试获取锁时,如果锁已经被其他进程或线程持有,它会等待一段时间,直到锁变为可用状态。
     *                   waitTime就是这个等待时间的上限。如果在这段时间内锁没有被释放,则获取锁的尝试会失败。这个参数有助于防止在锁资源上的长时间阻塞。
     * @param leaseTime  这个参数表示一旦获取了锁之后,锁将会被保持多长时间。在leaseTime期满后,锁会自动被释放。
     *                   这是一种安全措施,以防止某个进程或线程在持有锁之后忘记释放它,或因为崩溃而无法释放,从而导致其他线程或进程永远无法获取这个锁。
     *                   设置合理的leaseTime可以确保即使出现这样的情况,锁最终也会被释放,从而使得其他进程能够获取锁。
     * @return 是否抢锁成功,true:抢锁成功,false: 抢锁失败
     */
    public boolean tryLockWithWaitTimeAndLeaseTime(String prefix, String businessNo, int waitTime, int leaseTime) {
        RLock lock = client.getLock(prefix + SPLIT + businessNo);
        try {
            return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            return false;
        }
    }


    /**
     * 尝试获取分布式锁,带有尝试获取锁的等待时间
     *
     * @param prefix     业务号前缀
     * @param businessNo 业务号
     * @param waitTime   使用场景:例如,抽奖,在1秒内若该用户没有抢锁成功,则给用户返回系统繁忙,请稍后再试的文案, 单位:秒
     *                   这个参数决定了在尝试获取锁时的最长等待时间。当你的程序尝试获取锁时,如果锁已经被其他进程或线程持有,它会等待一段时间,直到锁变为可用状态。
     *                   waitTime就是这个等待时间的上限。如果在这段时间内锁没有被释放,则获取锁的尝试会失败。这个参数有助于防止在锁资源上的长时间阻塞。
     * @return 是否抢锁成功, true: 抢锁成功, false: 抢锁失败
     */
    public boolean tryLockWithWaitTime(String prefix, String businessNo, int waitTime) {
        RLock lock = client.getLock(prefix + SPLIT + businessNo);
        try {
            return lock.tryLock(waitTime, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            return false;
        }
    }

    /**
     * 尝试获取分布式锁 抢锁失败后,不会等待,立即返回成功或失败
     *
     * @param prefix     业务号前缀
     * @param businessNo 业务号,
     * @return 使用场景:例如,抽奖,若该用户没有抢锁成功,则立即给返回用户系统繁忙,请稍后再试的文案
     * 是否抢锁成功, true: 抢锁成功, false: 抢锁失败
     */
    public boolean tryLock(String prefix, String businessNo) {
        RLock lock = client.getLock(prefix + SPLIT + businessNo);
        return lock.tryLock();
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值