• 26.可重入锁与不可重入锁


    可重入锁与不可重入锁

     引言

    本节介绍的是可重入锁和不可重入锁。可指的是可以,不可指的是不可以。重入指的是重复进入同步作用域。这里的同步作用域可以是同步代码块,也可以是同步方法或者是lock锁同步代码,无论是进入哪一个同步作用域,都意味着同步锁被重复使用。所以重入也有重复使用同步锁的意思。锁指的是同步锁,综上锁述,可重入锁指的是可以重复使用的同步锁。不可重入锁指的是不可以重复使用的同步锁。那么哪些锁是可承认锁,哪些锁是不可承认锁呢?


    这张表列举了可重入锁与不可重入锁对象,可重复有
    4个,分别是synchronize,reentrantlock和reentrantreadwritelock.Readlock以及writelocke,不可重入锁没有内置对象,需要我们自己实现。本节的最后我们会去实现一个不可重入锁。下面我们分别来演示可重入锁与不可重入锁。

    可重入锁

    首先演示的是可重入锁,以同步代码为例,写一个同步锁为main.class的同步代码块,在代码块中输出一句话,然后再在同步代码块中写一个同步锁为main.class的同步代码块,目的是测试同步锁是否能重复使用。 


    接着在第二个同步代码块中也输出一句话,观察执行结果。

    从执行结果来看,程序顺利执行,说明同步代码块上的同步锁可重复使用。

    再来看看同步方法的实例,我们知道同步方法分为静态与非静态,这里我们就以静态同步方法为例,定义一个静态同步方法Printa,他的同步锁为类名点class,也就是main.class,然后在Printa方法中说出一句话,接着再定义一个静态同步方法printb,同步锁也为main.class,在printb方法中也说出一句话,然后在printerA A方法中调用printb,目的是测试同步锁是否可重复使用,最后在main方法中调用printa观察执行结果。 

    从执行结果来看,程序顺利执行,说明同步方法上的同步锁可重复使用。

    再来看看可重组锁的最后一个例子,创建一个lock锁,new一个reentrantlock对象,调用它的lock方法获取锁,写上try finally代码块,在finally代码块中调用unlook方法释放锁。在try代码块中说出一句话,接着再次调用lock方法获取锁,目的是测试lock锁是否可重复使用。同样的写上try---finally代码块,在finally代码块中调用unlock方法释放锁,最后在try代码块中输出一句话,观察执行结果。 

    从执行结果来看,程序顺利执行

    说明reentrantlock锁可重复使用,可重入锁演示完毕

    不可重入锁

    接下来来看看不可重入锁,因为不可重锁没有内置对象,所以需要我们自己去实现一个不可重入锁。这里我们先理清一下实践的思路,既然是锁,锁以我们首先要实现的是lock接口,这个毋庸置疑,因为lock接口里面,它定义了同步锁的规则,实现它里面的规则,就算是自定义好了一把锁,然后我们需要绑定已经获取到锁的线程,这一步必不可少。哪一个线程获取到了锁,需要记录下来,保证同一时刻只有一个线程拿到锁。 


    接着我们要去实现获取锁的方法,也就是实现
    lock接口中的lock方法。最后我们还需要实现释放锁的方法,也就是实现lock接口中的 unlock方法。

    下面我们就按照这个思路,开始自定义一个不可重入锁,定义一个类。unreentrantlock。实现locker接口。重写lock接口中的方法,它里面一共有6个方法,我们不需要全部都实现,着重实现lock和unlock方法就可以了。定义一个thread类型的属性,用于记录已获取锁的线程。

    接下来我们先来实现lock方法,写一个同步锁为this的同步代码块,目的是同一时刻最多只有一个线程执行绑定操作,使用while循环,判断当前是否已经绑定过线程,当已经绑定过线程时,使当前线程等待等待下一次绑定。 


    如果当前没有绑定任何线程,则绑定当前线程。

    至此lock方法编写完毕,再来编写unlock方法。同样的写上同步锁为this的同步代码块,目的是同一时刻最多只有一个线程执行解绑操作,判断当前线程是否为绑定线程。如果不是直接return,如果是则解绑线程,将thread置为null,并唤醒所有等待的线程,这些被唤醒的线程他们可以继续绑定。

    至此unlook方法编写完毕,整个已经全部编写完毕。下面来使用该锁,还是之前的例子,将可重入锁reentrantlock改为unreentrantlock

    运行程序观察执行结果。 


    从执行结果来看,程序只打印了第一次获取锁,然后就进入了等待,说明不可重入锁发挥的作用,至此不可重入锁演示完毕。

    总结

    最后总结一下本节的内容,本节介绍了可重入锁与不可重入锁相关的概念和对象,在这里就不再赘述了。在实际开发中可重入锁用的非常多,不可重锁几乎不会用到。 


      

    附录:

    笔记完整文本:

    本节介绍的是可重入锁与,不可重入锁可指的是可以,不可指的是不可以重入,指的是重复进入同步作用域。这里的同步做英语可以是同步代码块,也可以是同步方法或者是洛克索同步代码,无论是进入哪一个同步作用域,都意味着同步锁被重复使用。锁以重入也有重复使用同步锁的意思。锁指的是同步锁,综上锁述,可重入锁指的是可以重复使用的,同步锁不可重入锁指的是不可以重复使用的同步锁。那么哪些锁是可承认锁,哪些锁是不可承认锁呢? 这张表列举了可重入锁与不可重入锁对象,可重复有4个,分别是生根带子的 reign trend locker和Renn trend ree dried locker点Reed locker以及write locker,不可承认锁没有内置对象,需要我们自己实现。本节的最后我们会去实现一个不可重入锁。下面我们分别来演示可重入锁与不可重入数。首先演示的是可重入锁,以同步代码为例,写一个同步锁为闷点class的同步代码块,在代码块中输出一句话,然后再在同步代码块中写一个同步锁谓论点class的同步代码块,目的是测试同步锁是否能重复使用。 接着在第二个同步代码块中也说出一句话,观察执行结果。从执行结果来看,程序顺利执行,说明同步代码块上的同步锁可重复使用。再来看看同步方法的实例,我们知道同步方法分为静态与非静态,这里我们就以静态同步方法为例,定义一个静态同步方法。Print a他的同步锁谓类名点class,也就是孟典克拉斯,然后在pro的a方法中说出一句话,接着再定义一个静态同步方法,print b同步锁也为梦点class,在print b方法中也说出一句话,然后在printer的AA方法中调用print bea目的是测试同步锁,是否可重复使用,最后在main方法中调用print a观察执行结果。 从执行结果来看,程序顺利执行,说明同步方法上的同步锁可重复使用。再来看看可重组锁的最后一个例子,创建一个logo锁,你有一个rent的logo对象,调用它的log方法获取锁,写上try finally代码块在finally代码块中调用on look方法释放锁。在创业代码块中说出一句话,接着再次调用look方法获取锁,目的是测试logo锁是否可重复使用。同样的写上串finally大板块,在finally代码块中调用on look方法释放锁,最后在踹板块中说出一句话,观察执行结果。 从执行结果来看,程序顺利执行,说名为entry的洛克锁可重复使用,可重入锁演示完毕,接下来来看看不可重入锁,因为不可重锁没有内置对象,锁以需要我们自己去实现一个不可从容锁。这里我们先理清一下实践的思路,既然厕锁锁以我们首先要实现的是logo接口,这个毋庸置疑,因为look接口里面它定义了同步手的规则,实现它里面的规则,就算是自定义好了一把锁,然后我们需要绑定已经获取到锁的线程,这一步必不可少。哪一个线程获取到了数,需要记录下来,保证同一时刻只有一个线程拿到锁。 接着我们要去实现获取锁的方法,也就是实现look接口中的logo方法。最后我们还需要实现释放锁的方法,也就是实现logo接口中的 unlock方法。下面我们就按照这个思路开始自定义一个不可重入锁,定义一个类。On rain trend locker。实现locker接口。重写logo接口中的方法,它里面一共有6个方法,我们不需要全部都实现,着重实现logo和on locker方法就可以了。定义一个three类型的属性,用于记录已获取锁的线程。接下来我们先来实现look方法,写一个同步锁为zs的同步代码块,目的是同一时刻最多只有一个线程执行绑定操作,使用VR循环,判断当前是否已经绑定过线程,当已经绑定过线程时,使当前线程等待等待下一次绑定。 如果当前没有绑定任何线程,则绑定当前线程。至此note方法编写完毕,再来编写on look方法。同样的写上同步锁为js的同步代码块,目的是同一时刻最多只有一个线程执行解绑操作,判断当前线程是否为绑定线程。如果不是直接return,如果是则解绑线称,将thread置为浪,并唤醒锁有等待的线程,这些被唤醒的线程他们可以继续保密。至此on,look方法编写完毕,整个Ahn rent、rundll Oakley也已经全部编写完毕。下面来使用该锁,还是之前的例子,将可重入锁retrain的locker改为online trade locker运行程序观察执行结果。 从执行结果来看,程序只打印了第一次获取锁,然后就进入了等待,说明不可从容锁发挥的作用,至此不可重入锁也手很闭。最后总结一下本节的内容,本节介绍了可重入锁与不可重入锁相关的概念和对象,在这里就不再赘述了。在实际开发中可出入锁用的非常多,不可重锁几乎不会用到。

  • 相关阅读:
    pandas高效实现条件逻辑
    Python教程:文件、异常处理和其他
    最终初学者指南,以数据科学用例赢得分类黑客马拉松
    用Nvidia Jetson Nano 2GB和Python构建一个价值60美元的人脸识别系统
    一幅图像能顶16x16字!——用于大规模图像缩放识别的变压器(对ICLR 2021年论文的简要回顾)
    接缝雕刻算法:一种看似不可能的图像大小调整方法
    apache与nginx的优缺点的比较
    php5与php7的区别
    git基本的命令大全
    redis和membercache的区别
  • 原文地址:https://www.cnblogs.com/cj8357475/p/16086082.html
Copyright © 2020-2023  润新知