该类是一个读写锁的改进,它的思想是读写锁中读不仅不阻塞读,同时也不应该阻塞写。

读不阻塞写的实现思路:

在读的时候如果发生了写,则应当重读而不是在读的时候直接阻塞写!

因为在读线程非常多而写线程比较少的情况下,写线程可能发生饥饿现象,也就是因为大量的读线程存在并且读线程都阻塞写线程,

因此写线程可能几乎很少被调度成功!当读执行的时候另一个线程执行了写,则读线程发现数据不一致则执行重读即可。所以读写都存在的情况下,

使用StampedLock就可以实现一种无障碍操作,即读写之间不会阻塞对方,但是写和写之间还是阻塞的!

StampedLock的实现思想

在StampedLock中使用了CLH自旋锁,如果发生了读失败,不立刻把读线程挂起,锁当中维护了一个等待线程队列。

所有申请锁但是没有成功的线程都会记录到这个队列中,每一个节点(一个节点表示一个线程)保存一个标记位(locked),

用于判断当前线程是否已经释放锁。当一个未标记到队列中的线程试图获得锁时,会取得当前等待队列尾部的节点作为其前序节点,

并使用类似如下代码(一个空的死循环)判断前序节点是否已经成功的释放了锁:

while(pred.locked){  }

解释:pred表示当前试图获取锁的线程的前序节点,如果前序节点没有释放锁,则当前线程就执行该空循环并不断判断前序节点的锁释放,

即类似一个自旋锁的效果,避免被系统挂起。当循环一定次数后,前序节点还没有释放锁,则当前线程就被挂起而不再自旋,

因为空的死循环执行太多次比挂起更消耗资源。

读写锁StampedLock的思想的更多相关文章

  1. 源码分析:升级版的读写锁 StampedLock

    简介 StampedLock 是JDK1.8 开始提供的一种锁, 是对之前介绍的读写锁 ReentrantReadWriteLock 的功能增强.StampedLock 有三种模式:Writing(读 ...

  2. Java并发(8)- 读写锁中的性能之王:StampedLock

    在上一篇<你真的懂ReentrantReadWriteLock吗?>中我给大家留了一个引子,一个更高效同时可以避免写饥饿的读写锁---StampedLock.StampedLock实现了不 ...

  3. 正确使用Java读写锁

    JDK8中引入了高性能的读写锁StampedLock,它的核心思想在于,在读的时候如果发生了写,应该通过重试的方式来获取新的值,而不应该阻塞写操作.这种模式也就是典型的无锁编程思想,和CAS自旋的思想 ...

  4. Java8 读写锁的改进:StampedLock(笔记)

         StampedLock是Java8引入的一种新的所机制,简单的理解,可以认为它是读写锁的一个改进版本,读写锁虽然分离了读和写的功能,使得读与读之间可以完全并发,但是读和写之间依然是冲突的,读 ...

  5. 【漫画】读写锁ReadWriteLock还是不够快?再试试StampedLock!

    本文来源于公众号[胖滚猪学编程] 转载请注明出处! 在互斥锁ReentrantLock不好用?试试读写锁ReadWriteLock一文中,我们对比了互斥锁ReentrantLock和读写锁ReadWr ...

  6. [JDK8]读写锁的改进:StampedLock

    StampedLock是Java8引入的一种新的锁机制,简单的理解,可以认为它是读写锁的一个改进版本,读写锁虽然分离了读和写的功能,使得读与读之间可以完全并发,但是读和写之间依然是冲突的,读锁会完全阻 ...

  7. 【Java并发工具类】StampedLock:比读写锁更快的锁

    前言 ReadWriteLock适用于读多写少的场景,允许多个线程同时读取共享变量.但在读多写少的场景中,还有更快的技术方案.在Java 1.8中, 提供了StampedLock锁,它的性能就比读写锁 ...

  8. java并发编程-StampedLock高性能读写锁

    目录 一.读写锁 二.悲观读锁 三.乐观读 欢迎关注我的博客,更多精品知识合集 一.读写锁 在我的<java并发编程>上一篇文章中为大家介绍了<ReentrantLock读写锁> ...

  9. Linux多线程实践(6) --Posix读写锁解决读者写者问题

    Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *rest ...

随机推荐

  1. Hibernate 初体验

    为什么会产生 Hibernate Mybatis 这类的dao层框架 传统的jdbc 虽然执行速度很快,但是开发效率很低,随着面向对象开发的设计思想,在面向对象编程中 将对象 进行持久化,存入关系型的 ...

  2. RabbitMQ入门教程(十一):消息属性Properties

    原文:RabbitMQ入门教程(十一):消息属性Properties 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ...

  3. PHP foreach 引用 &

    以前用foreach,总喜欢在第二次遍历时改变value的拼写,比如 $x = array("a", "b", "c"); foreach ...

  4. C语言IOCP

    C语言的IOCP example #include <winsock2.h> #include <ws2tcpip.h> #include <mswsock.h> ...

  5. 阿里云CentOs服务器 安装与配置mysql数据库

    阿里云CentOs服务器 安装与配置mysql数据库 以上为Linux安装mysql数据库 Linux 安装mysql 数据库 一下为mysql 安装教程 Using username "r ...

  6. css的样式问题

    项目里面遇到一个布局: 然后侧边栏菜单的高度要随着内容的高度变化而变化:所以在这里贴一下代码:效果如下 <!DOCTYPE html> <html lang="en&quo ...

  7. node端口被占用

    Error: listen EADDRINUSE :::8000 at Object._errnoException (util.js:992:11) at _exceptionWithHostPor ...

  8. Nginx进行UDP的负载均衡

    准备工作: 服务器1:192.168.33.102     搭建nginx服务,作为反向代理的中转站 服务器2:192.168.33.103    nginx要反向代理的服务器 一.在服务器1上搭建n ...

  9. tf.get_variable函数的使用

    tf.get_variable(name,  shape, initializer): name就是变量的名称,shape是变量的维度,initializer是变量初始化的方式,初始化的方式有以下几种 ...

  10. Linux 软件的下载安装

    一.Linux系统安装软件的方式有两种: 1.通过 Linux 资源服务(类似于APP Shop)直接安装 2.下载tar包,解压安装.   二.Linux 资源服务安装软件 1.提示:一般安装一个软 ...