Java并发编程原理与实战三十九:JDK8新增锁StampedLock详解

1、StampedLock是做什么的?

—–》它是ReentrantReadWriteLock 的增强版,是为了解决ReentrantReadWriteLock的一些不足。   2、ReentrantReadWriteLock有什么不足之处呢? ——》我们都知道,ReentrantReadWriteLock是读写锁,在多线程环境下,大多数情况是读的情况远远大于写的操作,因此可能导致写的饥饿问题。(换人话来说的话,读操作一直都能抢占到CPU时间片,而写操作一直抢不了)   3、为什么会导致写操作会出血饥饿问题呢? —–》ReentrantReadWriteLock
写锁的互斥的 (读和读—不互斥,
读和写—互斥,写和写—-互斥),懂了吗?   4、正因为ReentrantReadWriteLock出现了
读和写是互斥的情况,这个地方需要优化,因此就出现了StampedLock!   5、StampedLock是读锁并不会阻塞写锁。这里就有朋友会问,如果这样设计的话,那么怎样保证读和写的一致性呢? —–》StampedLock的设计思路也比较简单,就是在读的时候发现有写操作,再去读多一次。(思想上来说)   6、那下一个问题就是StampedLock是怎样知道读的时候发生了写操作呢? —–》我们的StampedLock有两种锁,一种是悲观锁,另外一种是乐观锁。如果线程拿到乐观锁就读和写不互斥,如果拿到悲观锁就读和写互斥。   7、看StampedLock源码的时候,可以看writeLock()和trywriteLock(),
tryOptimisticRead()这是本API中最有亮点的方法(乐观锁)。
 
  ==============================================================     public class Demo { private int balance; private StampedLock lock = new StampedLock(); public void conditionReadWrite (int value) { // 首先判断balance的值是否符合更新的条件 long stamp = lock.readLock(); while (balance > 0) { long writeStamp = lock.tryConvertToWriteLock(stamp); if(writeStamp != 0) { // 成功转换成为写锁 stamp = writeStamp; balance += value; break; } else { // 没有转换成写锁,这里需要首先释放读锁,然后再拿到写锁 lock.unlockRead(stamp); // 获取写锁 stamp = lock.writeLock(); }   } lock.unlock(stamp); } public void optimisticRead() { long stamp = lock.tryOptimisticRead(); int c = balance; // 这里可能会出现了写操作,因此要进行判断 if(!lock.validate(stamp)) { // 要从新读取 long readStamp = lock.readLock(); c = balance; stamp = readStamp; } ///  lock.unlockRead(stamp); } public void read () { long stamp = lock.readLock(); lock.tryOptimisticRead(); int c = balance; // … lock.unlockRead(stamp); } public void write(int value) { long stamp = lock.writeLock(); balance += value; lock.unlockWrite(stamp); }   }   ====================================================   StampedLock的性能是远远好过ReentrantReadWriteLock的。那为什么还存在ReentrantReadWriteLock呢? ——》根据我们上述的代码,我们知道使用StampedLock,编写代码上相对繁琐些。ReentranReadWriteLock比较简单些。    
悲观锁:每次拿数据的时候就去锁上。
乐观锁:每次去拿数据的时候,都没锁上,而是判断标记位是否有被修改,如果有修改就再去读一次。
(就像很多个人去桌子上看今天老师布置的作业题,另外桌子旁边有一个牌子,红色面代表“作业题已经被修改过了”,白色面代表“题目是最新的”。第一个人去看作业题,再看了下牌子,牌子是白色的,作业题是最新的。但是有一个人去看作业题,看完之后,再看隔壁的牌子,牌子变成红色了,于是他赶紧回去看了一下题目,果然题目已经被改过了,于是他再看了一次,再确认一次牌子颜色,都没问题之后,就放心走了。)

 

    原文作者:java锁
    原文地址: https://www.cnblogs.com/pony1223/p/9552093.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞