【Redission实现分布式锁lock()和tryLock()方法】

本文详细比较了Redisson库中的lock()和tryLock()方法在配置、行为和应用场景上的区别,lock()为阻塞获取,可能造成线程堵塞,而tryLock()是非阻塞的,适合处理高并发场景。
摘要由CSDN通过智能技术生成

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:在工作中使用到redis,摸鱼中学习,redission


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Redisson配置

示例:在Springboot配置

二、lock()和tryLock()的区别

代码借用 链接: Redission实现分布式锁lock()和tryLock()方法的区别

1. lock()

自己占用锁30秒,如果业务在30内处理完,释放锁;如果业务超过30秒,在30s会释放锁。

  lock.lock(30, TimeUnit.SECONDS);    // 尝试在30秒内获取锁,如果获取不到则放弃

代码如下(示例): 任务需要20s

    public String RedissonLock2() {
        RLock lock = redissonClient.getLock("order_lock");
        boolean success = true;
        try {
            System.out.println(Thread.currentThread().getName()+"获取锁前的时间:"+LocalDateTime.now());
            // 尝试在30秒内获取锁(等待获取锁30秒)
            lock.lock(30, TimeUnit.SECONDS);
            System.out.println(Thread.currentThread().getName()+"获取锁后的时间:"+LocalDateTime.now());
            // 模拟业务处理耗时
            System.out.println(Thread.currentThread().getName() +  "模拟业务处理耗时20s:"+LocalDateTime.now());
            // TimeUnit.SECONDS.sleep(3);
            // 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。
            TimeUnit.SECONDS.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 判断当前线程是否持有锁
            if (success && lock.isHeldByCurrentThread()) {
                //释放当前锁
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + "释放锁"+ LocalDateTime.now());
            }
        }
        return "";
    }

运行图:

在这里插入图片描述
第二次是堵塞的;

上述代码:如果第一次请求:获取锁时间为10s、业务处理需要20s ; 第二次请求:获取锁时间为10s、业务处理需要20s ;

// 第一次部分代码修改--其他不变.....
        lock.lock(10, TimeUnit.SECONDS);
            System.out.println(Thread.currentThread().getName()+"获取锁后的时间:"+LocalDateTime.now());
            // 模拟业务处理耗时
            System.out.println(Thread.currentThread().getName() +  "模拟业务处理耗时20s:"+LocalDateTime.now());
            // TimeUnit.SECONDS.sleep(3);
            // 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。
            TimeUnit.SECONDS.sleep(20);
            //.....
// 第一次部分代码修改--其他不变.....
        lock.lock(30, TimeUnit.SECONDS);
            System.out.println(Thread.currentThread().getName()+"获取锁后的时间:"+LocalDateTime.now());
            // 模拟业务处理耗时
            System.out.println(Thread.currentThread().getName() +  "模拟业务处理耗时20s:"+LocalDateTime.now());
            // TimeUnit.SECONDS.sleep(3);
            // 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。
            TimeUnit.SECONDS.sleep(20);
            //.....

运行图:

在这里插入图片描述
第一次获取锁10s,业务结束耗时20s,由于业务超时锁在10s结束,第二个堵塞10s,获取锁持有时间30s,业务处理20s,20s后正常释放锁。

如果上述代码;第一次请求:获取锁时间为30s、业务处理需要20s ; 第二次请求:获取锁时间为10s、业务处理需要20s 。

第一次获取锁30s,业务结束耗时20s,由于业务完成锁在20s释放,第二个堵塞20s,获取锁持有时间10s,业务结束耗时20s,由于业务超时锁在10s结束

在这里插入图片描述

1). lock() 总结

使用 lock() ,会出现堵塞,在 lock.lock(30, TimeUnit.SECONDS)获取时间内等待其他线程释放才能执行。lock() 方法是阻塞获取锁的方式,如果当前锁被其他线程持有,则当前线程会一直阻塞等待获取锁,直到获取到锁或者发生超时或中断等情况才会结束等待。

2. tryLock()方法

当锁被其他占有时,等待5尝试获取锁,如果5s内获取不到,会立即废弃返回false;如果获取持有30s

//尝试获取锁,等待5秒,持有锁10秒钟
boolean success = lock.tryLock(5, 10, TimeUnit.SECONDS);   
 success = lock.tryLock(5,TimeUnit.SECONDS);  // 尝试获取锁,等待5秒

代码如下(示例):


    public String RedissonLock1() {
        RLock lock = redissonClient.getLock("order_lock");
        boolean success = true;
        try {
            System.out.println(Thread.currentThread().getName() + "获取锁前的时间:"+LocalDateTime.now());
            // 尝试获取锁,等待5秒,持有锁30秒钟
            success = lock.tryLock(5, 30, TimeUnit.SECONDS);
            // lock.lock(0, TimeUnit.SECONDS);
            System.out.println(Thread.currentThread().getName() + "获取锁后的时间:"+LocalDateTime.now());
            if (success) {
                System.out.println(Thread.currentThread().getName() + "获取到锁"+ LocalDateTime.now());
                // 模拟业务处理耗时
                // TimeUnit.SECONDS.sleep(3);
                // 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。
                System.out.println(Thread.currentThread().getName() +"模拟业务处理耗时20s:"+ LocalDateTime.now());
                TimeUnit.SECONDS.sleep(20);
            } else {
                System.out.println(Thread.currentThread().getName() + "未能获取到锁,已放弃尝试");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 判断当前线程是否持有锁
            if (success && lock.isHeldByCurrentThread()) {
                //释放当前锁
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + "释放锁"+ LocalDateTime.now());
            }
        }
        return "";
    }

    

运行结果图:

在这里插入图片描述
锁被占用时,第二次会尝试获取锁,在5s获取不到,立即放弃,业务不执行;

如果上述代码;第一次请求:等待5s、获取锁时间为30s、业务处理需要20s ; 第二次请求:获取锁时间为25s、获取锁时间为30s、业务处理需要20s 。

运行结果图:

在这里插入图片描述

第一次:开始请求,尝试5s获取锁,锁没有占用直接获取,不用等待5s,持有30s,业务执行20s;业务执行完还在持有时间内,释放锁在20s后。

第二次:开始请求,尝试在25s获取锁,25s内(开始请求时间不同,并非同时,并非在20s获取到锁),其他线程将锁释放或者中断,获取到锁,持有30s,第二次请求耗时总计total='业务处理耗时' + '尝试获取锁耗时'

1). lock.tryLock() 总结

使用 lock() ,会出现堵塞,而tryLock() 方法是一种非阻塞获取锁的方式,在尝试获取锁时不会阻塞当前线程,而是立即返回获取锁的结果,如果获取成功则返回 true,否则返回 false。


总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值