分布式Redis锁 - RedissonClient

Redis Java Client选型-Jedis Lettuce Redisson
最常用的可重入锁(Reentrant Lock) 先写个单元测试试一下
public class RedisLockTest {

    private RedissonClient redissonClient;

    //请求的key
    private static final String demo ="u001";

    //模拟短时间内的并发请求量

    private static final int threadNum =5;

    @Before
    public void init(){
        Config config = new Config();
        config.useSingleServer().setAddress("redis://120.78.144.70:6379");
        this.redissonClient = Redisson.create(config);

        System.out.println(Thread.currentThread().getName()+"是否存在key"+redissonClient.getLock(demo).isExists());
    }

    private class UserRequest implements Runnable{

        private CountDownLatch cdl;

        public UserRequest(CountDownLatch latch){
            this.cdl=latch;
        }

        @Override
        public void run() {
            try {
                if (redissonClient.getLock(demo).tryLock(0L,-1L, TimeUnit.SECONDS)) {
                    System.out.println(Thread.currentThread().getName()+"获取锁成功");
                    Thread.sleep(5000);
                    redissonClient.getLock(demo).unlock();
                    System.out.println(Thread.currentThread().getName()+"释放锁成功");
                }else{
                    System.out.println(Thread.currentThread().getName()+"获取锁失败"+"是否存在key"+redissonClient.getLock(demo).isExists());
                }
            }catch (Exception e) {
                e.printStackTrace();
            }finally {
                //倒计时计数一次
                cdl.countDown();
            }
        }
    }

    @Test
    public void testRedissonLock(){
        CountDownLatch cdl=new CountDownLatch(threadNum);
        Executor executor = Executors.newFixedThreadPool(threadNum);
        try{
            for (int i =0; i< threadNum; i++) {
                if(i==2){
                    //模拟在业务代码没执行完毕时另一个线程获取锁
                    Thread.sleep(1500);
                }
                executor.execute(new UserRequest(cdl));
            }
            //阻塞主线程,等待所有的子线程执行完毕
            cdl.await();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

分布式锁的实现分析参考
https://www.jianshu.com/p/a8b3473f9c24

比较关注的一个参数一个是过期时间,一个是定时续约过期时间

通过阅读源码知道lesstime参数决定是否续约

    private <T> RFuture<Long> tryAcquireAsync(long leaseTime, TimeUnit unit, final long threadId) {
        if (leaseTime != -1L) {
            return this.tryLockInnerAsync(leaseTime, unit, threadId, RedisCommands.EVAL_LONG);
        } else {
            RFuture<Long> ttlRemainingFuture = this.tryLockInnerAsync(this.commandExecutor.getConnectionManager().getCfg().getLockWatchdogTimeout(), TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);
            ttlRemainingFuture.addListener(new FutureListener<Long>() {
                public void operationComplete(Future<Long> future) throws Exception {
                    if (future.isSuccess()) {
                        Long ttlRemaining = (Long)future.getNow();
                        if (ttlRemaining == null) {
                            RedissonLock.this.scheduleExpirationRenewal(threadId);
                        }

                    }
                }
            });
            return ttlRemainingFuture;
        }
    }

总结一点

if(leaseTime==-1L){
    开启自动续期的定时任务,不断重置过期时间为lockWatchdogTimeout
    定时任务的频率为lockWatchdogTimeout配置时间的1/3
}else{
    不自动续期
    设置过期时间为leaseTime
}

所有属性介绍 https://yq.aliyun.com/articles/551640/

其他锁类型的锁参考
(联锁,红锁,读写锁,信号量,可过期性信号量)
https://blog.csdn.net/l1028386804/article/details/73523810

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

占星安啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值