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并发编程原理与实战三十九:JDK8新增锁StampedLock详解的更多相关文章

  1. Java并发编程原理与实战四十:JDK8新增LongAdder详解

    传统的原子锁AtomicLong/AtomicInt虽然也可以处理大量并发情况下的计数器,但是由于使用了自旋等待,当存在大量竞争时,会存在大量自旋等待,而导致CPU浪费,而有效计算很少,降低了计算效率 ...

  2. Java并发编程原理与实战三十二:ForkJoin框架详解

    1.Fork/Join框架有什么用呢? ------->Fork使用来切分任务,Join是用来汇总结果.举个简单的栗子:任务是1+2+3+...+100这个任务(当然这个任务的结果有好的算法去做 ...

  3. Java并发编程原理与实战三十五:并发容器ConcurrentLinkedQueue原理与使用

    一.简介 一个基于链接节点的无界线程安全队列.此队列按照 FIFO(先进先出)原则对元素进行排序.队列的头部 是队列中时间最长的元素.队列的尾部 是队列中时间最短的元素.新的元素插入到队列的尾部,队列 ...

  4. Java并发编程原理与实战三十四:并发容器CopyOnWriteArrayList原理与使用

    1.ArrayList的实现原理是怎样的呢? ------>例如:ArrayList本质是实现了一个可变长度的数组. 假如这个数组的长度为10,调用add方法的时候,下标会移动到下一位,当移动到 ...

  5. Java并发编程原理与实战三十六:阻塞队列&消息队列

    一.阻塞队列 1.阻塞队列BlockingQueue ---->可以理解成生产者消费者的模式---->消费者要等待到生产者生产出来产品.---->而非阻塞队列ConcurrentLi ...

  6. Java并发编程原理与实战三十八:多线程调度器(ScheduledThreadPoolExecutor)

    在前面介绍了java的多线程的基本原理信息:线程池的原理与使用 本文对这个java本身的线程池的调度器做一个简单扩展,如果还没读过上一篇文章,建议读一下,因为这是调度器的核心组件部分. 我们如果要用j ...

  7. Java并发编程原理与实战三十:CountDownLatch与CyclicBarrier 区别

    相信每个想深入了解多线程开发的Java开发者都会遇到CountDownLatch和CyclicBarrier,大家也在网上看到各种介绍原理,代码的,以及他们区别(应付面试)的,但是很少能讲清楚:他们到 ...

  8. Java并发编程原理与实战二十九:Exchanger

    一.简介 前面三篇博客分别介绍了CyclicBarrier.CountDownLatch.Semaphore,现在介绍并发工具类中的最后一个Exchange.Exchange是最简单的也是最复杂的,简 ...

  9. Java并发编程原理与实战三十一:Future&FutureTask 浅析

    一.Futrue模式有什么用?------>正所谓技术来源与生活,这里举个栗子.在家里,我们都有煮菜的经验.(如果没有的话,你们还怎样来泡女朋友呢?你懂得).现在女票要你煮四菜一汤,这汤是鸡汤, ...

随机推荐

  1. Monty Hall 问题与贝叶斯定理的理解

     三门问题(Monty Hall problem),是一个源自博弈论的数学游戏问题,大致出自美国的电视游戏节目Let's Make a Deal.问题的名字来自该节目的主持人蒙提·霍尔(Monty H ...

  2. 23_IO_第23天(字节流、字符流)_讲义

    今日内容介绍 1.字节流 2.字符流 01输入和输出 * A:输入和输出 * a: 参照物 * 到底是输入还是输出,都是以Java程序为参照 * b: Output * 把内存中的数据存储到持久化设备 ...

  3. Mac下不能安装第三方下载软件

    1.安装成功后,启动时如提示“某某文件已损坏,打不开”,请将电脑的“系统偏好设置--安全性与隐私--通用”的允许从以下位置下载的应用程序设置为“任何来源”. 2.如果您的电脑上没有“任何来源”的选项, ...

  4. react +MUI checkbox使用

    PS:因项目采用MUI,故,在此所讲的checkbox组件为MUI里的checkbox 因checkbox组件里 oncheck函数没法判断复选框是否选中,故,若直接复用且通过state改变check ...

  5. [2017BUAA软工]个人项目心得体会:数独

    心得体会 回顾此次个人项目,感受比较复杂,最明显的一点是--累!代码编写.单元测试.代码覆盖.性能优化,环环相扣,有种从作业发布开始就一直在赶DDL的感觉,但是很充实,也学习到和体验了很多东西.最令人 ...

  6. java 调用 oracle的function 和 procedure

    1.调用函数 CallableStatement cs=con.prepareCall("{?=call get_pname(?,?,?)}"); 第一个?表示返回的值,后面的?可 ...

  7. 清理elasticsearch的索引

    curl -XDELETE 'http://172.16.1.16:9200/logstash-2013.03.*' 清理掉了所有 3月份的索引文件,其中*是通配符 下面是主页上的详细介绍,其他部分可 ...

  8. 二分图最大匹配模板(pascal)

    uoj#78. 二分图最大匹配 从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生.编号分别为 1,…,nl1,…,nl 和 1,…,nr1,…,nr. 有若干个这样的条件:第 vv  ...

  9. winform 利用委托实现窗体传值

    父窗体:Form1    ,有个 textbox1.text ,有个button1 子窗体:Form2  ,有个 textbox1.text ,有个button1 修改Form1 的textbox1. ...

  10. 使用jQuery在javascript中自定义事件

    js中的自定义事件有attachEvent,addEventListener等等好多种,往往受困于浏览器兼容,而且代码写起来也相当麻烦.jQuery为我们解决了这个问题,几行代码就可以很好的实现事件的 ...