4.9 ReentrantLock、ReentrantReadWriteLock、StampedLock实现原理以及特点;

ReentrantLock

java除了使用关键字synchronized外,还可以使用ReentrantLock实现独占锁的功能。
而且ReentrantLock相比synchronized而言功能更加丰富,使用起来更为灵活,也更适合复杂的并发场景。
ReentrantLock常常对比着synchronized来分析,我们先对比着来看然后再一点一点分析。

 (1)synchronized是独占锁,加锁和解锁的过程自动进行,易于操作,但不够灵活。
 ReentrantLock也是独占锁,加锁和解锁的过程需要手动进行,不易操作,但非常灵活。

 (2)synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;
 ReentrantLock也可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。

 (3)synchronized不可响应中断,一个线程获取不到锁就一直等着;
 ReentrantLock可以相应中断。

 ReentrantLock好像比synchronized关键字没好太多,我们再去看看synchronized所没有的,
 一个最主要的就是ReentrantLock还可以实现公平锁机制。
 什么叫公平锁呢?也就是在锁上等待时间最长的线程将获得锁的使用权。通俗的理解就是谁排队时间最长谁先执行获取锁。

ReentrantLock其原理主要是AQS和CAS机制。

ReentrantReadWriteLock

ReentrantLock就是一种排它锁。CountDownLatch是一种共享锁。

ReentrantReadWriteLock是同时包含排它锁和共享锁特性的一种锁,使用ReentrantReadWriteLock的写锁时,使用的便是排它锁的特性;使用ReentrantReadWriteLock的读锁时,使用的便是共享锁的特性。

https://www.cnblogs.com/xiaoxi/p/9140541.html
读写锁ReentrantReadWriteLock支持多个线程同时读,但是写操作时,不允许其他线程读或写。
一个是读操作相关的锁,称为共享锁;一个是写相关的锁,称为排他锁
读写锁有以下三个重要的特性:
(1)公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。
(2)重进入:读锁和写锁都支持线程重进入。
(3)锁降级:写锁能够降级成为读锁。

 ReentrantReadWriteLock实现了ReadWriteLock接口,ReadWriteLock接口定义了获取读锁和写锁的规范,具体需要实现类去实现;

对于获得写锁的线程,可以继续让它获取读锁,当它同时获取了写锁和读锁后,还可以先释放写锁继续持有读锁,这样一个写锁就“降级”为了读锁。
 一个线程要想同时持有写锁和读锁,必须先获取写锁再获取读锁;写锁可以“降级”为读锁;读锁不能“升级”为写锁。

StampedLock

https://www.liaoxuefeng.com/wiki/1252599548343744/1309138673991714
ReadWriteLock如果有线程正在读,写线程需要等待读线程释放锁后才能获取写锁,即读的过程中不允许写,这是一种悲观的读锁。
要进一步提升并发执行效率,Java 8引入了新的读写锁:StampedLock。
StampedLock和ReadWriteLock相比,改进之处在于:读的过程中也允许获取写锁后写入!
这样一来,我们读的数据就可能不一致,所以,需要一点额外的代码来判断读的过程中是否有写入,这种读锁是一种乐观锁。

乐观锁的意思就是乐观地估计读的过程中大概率不会有写入,因此被称为乐观锁。反过来,悲观锁则是读的过程中拒绝有写入,也就是写入必须等待。
显然乐观锁的并发效率更高,但一旦有小概率的写入导致读取的数据不一致,需要能检测出来,再读一遍就行。
和ReadWriteLock相比,写入的加锁是完全一样的,不同的是读取。注意到首先我们通过tryOptimisticRead()获取一个乐观读锁,并返回版本号。
接着进行读取,读取完成后,我们通过validate()去验证版本号,如果在读取过程中没有写入,版本号不变,验证成功,我们就可以放心地继续后续操作。
如果在读取过程中有写入,版本号会发生变化,验证将失败。在失败的时候,我们再通过获取悲观读锁再次读取。
由于写入的概率不高,程序在绝大部分情况下可以通过乐观读锁获取数据,极少数情况下使用悲观读锁获取数据。
可见,StampedLock把读锁细分为乐观读和悲观读,能进一步提升并发效率。
但这也是有代价的:一是代码更加复杂,二是StampedLock是不可重入锁,不能在一个线程中反复获取同一个锁。
小结
StampedLock提供了乐观读锁,可取代ReadWriteLock以进一步提升并发性能;
StampedLock是不可重入锁。
 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值