我们知道在解决线程安全问题上使用 ReentrantLock 就可以,但是 ReentrantLock 是独占锁,同时只有一个线程可以获取该锁,而实际情况下会有写少读多的场景,显然 ReentrantLock 满足不了需求,所以 ReentrantReadWriteLock 应运而生,ReentrantReadWriteLock 采用读写分离,多个线程可以同时获取读锁. 首先我们先看一下,ReentrantReadWriteLock 内部构造先看下它的类图结构如下图所示: 如上图可以看到读写锁内…
Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 本文内容:读写锁 ReentrantReadWriteLock 的源码分析,基于 Java7/Java8. 阅读建议:虽然我这里会介绍一些 AQS 的知识,不过如果你完全不了解 AQS,看本文就有点吃力了. 目录 使用示例 ReentrantReadWriteLock 总览 源码分析 读锁获取 读…
转载:https://blog.csdn.net/qq_19431333/article/details/70568478 ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁.读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的. 所有读写锁的实现必须确保写操作对读操作的内存影响.换句话说,一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容. 读写锁比互斥锁允许对于共享数据更大程度的并发.每次只能有一个写线程,但是同时可以有多个线程并发地读数据.ReadWriteLoc…
JUC 中倒数计数器 CountDownLatch 的使用与原理分析,当需要等待多个线程执行完毕后在做一件事情时候 CountDownLatch 是比调用线程的 join 方法更好的选择,CountDownLatch 与 线程的 join 方法区别是什么? 日常开发中经常会遇到需要在主线程中开启多线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后再进行汇总的场景,它的内部提供了一个计数器,在构造闭锁时必须指定计数器的初始值,且计数器的初始值必须大于0.另外它还提供了一个countDown…
关于AbstractQueuedSynchronizer中的独占锁,请参考ReentrantLock(http://www.cnblogs.com/bjorney/p/8040085.html) 1. ReentrantReadWriteLock // ReentrantReadWriteLock本身不提供加锁服务,只负责提供读锁和写锁public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializabl…
在上一篇<你真的懂ReentrantReadWriteLock吗?>中我给大家留了一个引子,一个更高效同时可以避免写饥饿的读写锁---StampedLock.StampedLock实现了不仅多个读不互相阻塞,同时在读操作时不会阻塞写操作. 为什么StampedLock这么神奇?能够达到这种效果,它的核心思想在于,在读的时候如果发生了写,应该通过重试的方式来获取新的值,而不应该阻塞写操作.这种模式也就是典型的无锁编程思想,和CAS自旋的思想一样.这种操作方式决定了StampedLock在读线程非…
一.前言 在分析了锁框架的其他类之后,下面进入锁框架中最后一个类ReentrantReadWriteLock的分析,它表示可重入读写锁,ReentrantReadWriteLock中包含了两种锁,读锁ReadLock和写锁WriteLock,可以通过这两种锁实现线程间的同步,下面开始进行分析. 二.ReentrantReadWriteLock数据结构 分析源码可以知道,ReentrantReadWriteLock底层是基于ReentrantLock和AbstractQueuedSynchroni…
概要 这一章,我们对HashMap进行学习.我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.内容包括:第1部分 HashMap介绍第2部分 HashMap数据结构第3部分 HashMap源码解析(基于JDK1.6.0_45)第3.1部分 HashMap的“拉链法”相关内容第3.2部分 HashMap的构造函数第3.3部分 HashMap的主要对外接口第3.4部分 HashMap实现的Cloneable接口第3.5部分 HashMap实现的Seria…
目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputStream 数据结构 2.2 ObjectOutputStream 构造函数 2.3 序列化入口:writeObject 2.4 核心方法:writeObject0 2.5 序列化:writeOrdinaryObject 2.6 类信息序列化:writeClassDesc 2.7 类数据信息序列化:w…
我们以ByteArrayInputStream,拉开对字节类型的“输入流”的学习序幕.本章,我们会先对ByteArrayInputStream进行介绍,然后深入了解一下它的源码,最后通过示例来掌握它的用法. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_02.html ByteArrayInputStream 介绍 ByteArrayInputStream 是字节数组输入流.它继承于InputStream.它包含一个内部缓冲区,该缓冲区包含从流…
前面学习ByteArrayInputStream,了解了“输入流”.接下来,我们学习与ByteArrayInputStream相对应的输出流,即ByteArrayOutputStream.本章,我们会先对ByteArrayOutputStream进行介绍,在了解了它的源码之后,再通过示例来掌握如何使用它. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_03.html ByteArrayOutputStream 介绍 ByteArrayOutpu…
目录 Java 序列化和反序列化(三)Serializable 源码分析 - 2 1. ObjectStreamField 1.1 数据结构 1.2 构造函数 2. ObjectStreamClass 2.1 数据结构 2.2 构造函数 2.3 提取序列号:getDeclaredSUID 2.4 提取需要序列化字段:getSerialFields 2.5 其它方法 Java 序列化和反序列化(三)Serializable 源码分析 - 2 在上一篇文章中围绕 ObjectOutputStream…
目录 前言 在多线程环境下,为了保证线程安全, 我们通常会对共享资源加锁操作,我们常用Synchronized关键字或者ReentrantLock 来实现,这两者加锁方式都是排他锁,即同一时刻最多允许一个线程操作,然而大多数场景中对共享资源读多于写,那么存在线程安全问题的是写操作(修改,添加,删除),我们是否应该考虑将读和写两个分开,只要运用合理,并发性能是不是可以提高,吞吐量增大呢? ReentrantReadWriteLock已经为我们实现了这种机制,我们一起来看它是怎样实现的吧! 1.读写…
本文结构 读写锁简介:介绍读写锁.读写锁的特性以及类定义信息 公平策略及Sync同步器:介绍读写锁提供的公平策略以及同步器源码分析 读锁:介绍读锁的一些常用操作和读锁的加锁.解锁的源码分析 写锁:介绍写锁的一些常用操作和写锁的加锁.解锁的源码分析 总结:总结全文,附读写锁全部源码理解 读写锁简介 在之前的文章提到了可重入锁,这是一种排他锁,核心原理是同一时间只允许一个线程访问.除了排他锁还有一种共享锁,这种锁在同一时间支持多线程同时访问, 将排他锁和共享锁进行组合便有了读写锁.读写锁维护了一组锁…
ReentrantReadWriteLock  源码分析: 1:数据结构: 成员变量: private final ReentrantReadWriteLock.ReadLock readerLock; //读取锁 private final ReentrantReadWriteLock.WriteLock writerLock; //写入锁 final Sync sync;    //Sync 对象,继承AQS对象 2:构造函数: public ReentrantReadWriteLock()…
概述 我们在介绍AbstractQueuedSynchronizer的时候介绍过,AQS支持独占式同步状态获取/释放.共享式同步状态获取/释放两种模式,对应的典型应用分别是ReentrantLock和Semaphore,AQS还可以混合两种模式使用,读写锁ReentrantReadWriteLock就是如此. 设想以下情景:我们在系统中有一个多线程访问的缓存,多个线程都可以对缓存进行读或写操作,但是读操作远远多于写操作,要求写操作要线程安全,且写操作执行完成要求对当前的所有读操作马上可见. 分析…
一.LongAdder原理 LongAdder类是JDK1.8新增的一个原子性操作类.AtomicLong通过CAS算法提供了非阻塞的原子性操作,相比受用阻塞算法的同步器来说性能已经很好了,但是JDK开发组并不满足于此,因为非常搞并发的请求下AtomicLong的性能是不能让人接受的. 如下AtomicLong 的incrementAndGet的代码,虽然AtomicLong使用CAS算法,但是CAS失败后还是通过无限循环的自旋锁不多的尝试,这就是高并发下CAS性能低下的原因所在.源码如下: p…
今天要介绍的是List接口中最常用的实现类——ArrayList,本篇的源码分析基于JDK8,如果有不一致的地方,可先切换到JDK8后再进行操作. 本篇的内容主要包括这几块: 1.源码结构介绍 2.源代码展示 3.要点说明 4.优缺点说明 一.源码结构介绍 ArrayList的源码跟之前的接口源码比起来,那可就不能同日而语了,一千多行代码,如果直接看的话确实有些费劲,但仔细看看就会发现,其实大致结构是这样的: 其中包含了好四个内部类:     ArrayListSpliterator:Array…
目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntegerFieldUpdater 无锁的Vector 无锁即无障碍的运行, 所有线程都可以到达临界区, 接近于无等待. 无锁采用CAS(compare and swap)算法来处理线程冲突, 其原理如下 CAS原理 CAS包含3个参数CAS(V,E,N).V表示要更新的变量, E表示预期值, N表示新值.…
该篇博客的有些内容和在之前介绍过了,在这里再次涉及到的就不详细说了,如果有不理解请看[Java]NIO中Channel的注册源码分析, [Java]NIO中Selector的创建源码分析 Selector的创建在Windows下默认生成WindowsSelectorImpl对象,那么Selector的select方法使用的就是WindowsSelectorImpl的select方法,而在WindowsSelectorImpl下并没有覆盖这个方法,而是由其基类SelectorImpl实现的: pu…
转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的spring工程,甚至是servlet工程,都是一样的,只不过配置一些监听器的方法不同而已. 本文经过作者实践,确认完美运行. 二:Spring boot使用websocket 2.1:依赖包 websocket本身是servlet容器所提供的服务,所以需要在web容器中运行,像我们所使用的tomcat,当然…
前面花了好几篇的篇幅把HashMap里里外外说了个遍,大家可能对于源码分析篇已经讳莫如深了.别慌别慌,这一篇来说说集合框架里最偷懒的一个家伙——HashSet,为什么说它是最偷懒的呢,先留个悬念,看完本文之后,你就会知道所言不假了. 本篇将从以下几点来进行介绍: 1.HashSet的特点和使用场景 2.HashSet的示例 3.HashSet的继承结构图 4.HashSet的源码解析 HashSet的特点和使用场景 HashSet是Set家族的一员,所以也具有着Set的全部性质,比如元素无序,元…
ReentrantReadWriteLock包含两把锁,一是读锁ReadLock, 此乃共享锁, 一是写锁WriteLock, 此乃排它锁. 这两把锁都是基于AQS来实现的. 下面通过源码来看看ReentrantReadWriteLock是如何做到读读共享,读写互斥的. 1. 测试代码  import java.util.concurrent.CyclicBarrier; import java.util.concurrent.locks.ReentrantReadWriteLock; publ…
前言 上一篇讲解了 AQS 的独占锁部分(参看:ReentrantLock 源码分析以及 AQS (一)),这一篇将介绍 AQS 的共享锁,以及基于共享锁实现读写锁分离的 ReentrantReadWriteLock.(若是遇到之前讲过的方法,将不再赘述) 先思考一下,为什么我们用读写锁分离? 我们知道 ReentrantLock 用的是独占锁,不管线程是读还是写状态,都会阻塞,这无疑会降低并发量. 但是,我们知道多个线程同时去读数据的时候,并不会产生线程安全的问题,因为它们互不干扰.那么为什么…
此处源码分析,主要是基于读锁,非公平机制,JDK1.8. 问题: 1.ReentrantReadWriteLock是如何创建读锁与写锁? 2.读锁与写锁的区别是什么? 3.锁的重入次数与获取锁的线程数分别是用哪种方式记录的? 4.当队列中出现多个共享模式的线程节点连续排列时,那么当第一个共享模式的线程拿到锁之后,后面的共享线程节点怎么获取锁? 一.创建ReadLock. ReentrantReadWriteLock rrw = new ReentrantReadWriteLock(); publ…
本文将主要讲述 AbstractQueuedSynchronizer 的内部结构和实现逻辑,在看本文之前最好先了解一下 CLH 队列锁,AbstractQueuedSynchronizer 就是根据 CLH 队列锁的变种实现的,因为本身 AQS 比较复杂不容易看清楚他本身的实现逻辑,所以查看 CLH 队列锁的实现,可以帮助我们理清楚他内部的关系:关于队列锁的内容可以参考 ,CLH.MCS 队列锁简介 : 一.AQS 结构概述 在 JDK 中除 synchronized 内置锁外,其他的锁和同步组…
目录 一.读写锁 二.悲观读锁 三.乐观读 欢迎关注我的博客,更多精品知识合集 一.读写锁 在我的<java并发编程>上一篇文章中为大家介绍了<ReentrantLock读写锁>,ReentrantReadWriteLock可以保证最多同时有一个线程在写数据,或者可以同时有多个线程读数据,但读写不能同时进行. 比如你正在做的是日志,有一个线程正在做写操作,但是在写日志的时候你可能需要把日志集中转移到集中管理日志服务,但是此时读线程不能读数据(因为无法获取读锁).面对这个需求,Ree…
package java.util.concurrent.locks; import java.util.concurrent.TimeUnit; import java.util.Collection; /** * 一个{@link ReadWriteLock}的实现 * 支持类似{@link ReentrantLock}的语义. * <p>这个类具有以下属性 * * <ul> * <li><b>Acquisition order</b> *…
概要 这一章,我们对HashMap进行学习.我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.内容包括:第1部分 HashMap介绍第2部分 HashMap数据结构第3部分 HashMap源码解析(基于JDK1.6.0_45)    第3.1部分 HashMap的“拉链法”相关内容    第3.2部分 HashMap的构造函数    第3.3部分 HashMap的主要对外接口    第3.4部分 HashMap实现的Cloneable接口    第3…
Object: 超类 (1)Object是类层次结构的顶层类,是所有类的根类,超类.   所有的类都直接或者间接的继承自Object类.   所有对象(包括数组)都实现这个类的方法 (2)Object类的常用方法:   A:toString()     public String toString():返回对象的字符串表示形式.     组成:包名...类名@内存地址值的十六进制 //toString源码: public String toString() { return getClass()…