day106-缓存-分布式锁-Redisson-可重入锁介绍及lock锁测试

1.可重入锁介绍 

什么是可重入锁,举个例子

现在我有锁对象lock,在调用A方法内,有用lock锁住

锁住后在A方法内有对B方法的调用,B方法内又有用lock锁住,

如果不是可重入锁,那么调用B方法时就死锁了,因为A方法内lock锁还不会释放,

如果是可重入锁,那么可以直接运行B方法,看到这你应该明白了,同一线程内,一旦获取到了某个锁,那么

线程后续执行还需要此锁,那么可以直接使用

想要详细了解参考:https://blog.csdn.net/yanyan19880509/article/details/52345422,然后自己去看相关源码

除了synchronize和ReentrantLock及子类,其他都是不可重入。当然借助AQS可自己实现重入锁

2.lock锁测试

IndexController内添加代码如下

    @RequestMapping({"/hello"})
    @ResponseBody
    public String hello(){

        //获取一把锁,只要名称一样就是同一把锁
        RLock lock = redissonClient.getLock("my-lock");
        //加锁 没加上锁的线程阻塞式等待,不用我们之前那样写的自旋
        lock.lock();
        //模拟业务执行
        System.out.println("加锁成功,业务执行中,执行线程为:"+Thread.currentThread().getId());
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //释放锁
            System.out.println("释放锁,执行线程为:"+Thread.currentThread().getId());
            lock.unlock();
        }

        return "hello";
    }

浏览器同时开俩窗口访问此方法

浏览器显示如下,可以看到一个线程获取锁,执行业务然后释放锁,然后再是另一个线程做同样的操作,没获取锁的线程就阻塞式等待直到锁被释放

以上看到了锁的基本功能,至于我们上一节说的前面,突然宕机或者停电锁没释放,又或者获取锁,解锁原子性问题等等,

Reddison是否有解决呢,简单测试下

现在测试的是一个线程一运行时,加锁之后释放锁之前宕机的问题,若宕机后没有释放锁,那么自然会死锁了

拷贝应用配置,更改端口后启动

启动两服务后访问

此时在10201端口中服务中的锁被获取后停止服务

看到10200服务中的锁依然能被获取,业务照常执行然后释放锁了

说明在宕机后锁被释放了,猜测应该是有一个默认过期时间的,所以在服务停止后锁会被释放,不止这一点,相信

获取锁与解锁的原子性等操作也有lock底层也有实现,业务如果允许时间长也不用担心业务没运行完锁就自动释放,在业务运行期间也会有每隔十秒自动续期的,

下一节带你看看底层代码如何实现的

猜你喜欢

转载自blog.csdn.net/JavaCoder_juejue/article/details/113794564