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运行程序观察执行结果。 从执行结果来看,程序只打印了第一次获取锁,然后就进入了等待,说明不可从容锁发挥的作用,至此不可重入锁也手很闭。最后总结一下本节的内容,本节介绍了可重入锁与不可重入锁相关的概念和对象,在这里就不再赘述了。在实际开发中可出入锁用的非常多,不可重锁几乎不会用到。
本文来自博客园,作者:小陈子博客,转载请注明原文链接:https://www.cnblogs.com/cj8357475/p/16086082.html