ReentrantReadWriteLock 源码分析
ReentrantReadWriteLock 源码分析:
1:数据结构:
成员变量:
private final ReentrantReadWriteLock.ReadLock readerLock; //读取锁
private final ReentrantReadWriteLock.WriteLock writerLock; //写入锁
final Sync sync; //Sync 对象,继承AQS对象
2:构造函数:
public ReentrantReadWriteLock() {
this(false);
}
public ReentrantReadWriteLock(boolean fair) { //默认 fair= false
sync = fair ? new FairSync() : new NonfairSync(); //默认创建一个 NonfairSync
readerLock = new ReadLock(this); //创建读取锁
writerLock = new WriteLock(this); //创建写入锁
}
3:接下来分析ReadLock 读取锁;
1):成员变量:
private final Sync sync; // ReadLock 内部维护的Sync对象,和ReentrantReadWriteLock中维护的Sync对象一致;
2):构造方法:
protected ReadLock(ReentrantReadWriteLock lock) {
sync = lock.sync; //将ReentrantReadWriteLock 构造函数中创建的Sync对象赋给ReadLock 中的Sync属性
}
4:下面分析ReadLock中的lock方法;
public void lock() {
sync.acquireShared(1);
}
acquireShared方法如下:
public final void acquireShared(int arg) { // arg=1
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
下面依次分析 tryAcquireShared doAcquireShared这两个方法:
1): tryAcquireShared 方法:
protected final int tryAcquireShared(int unused) { // unused=1
Thread current = Thread.currentThread(); //当前线程
int c = getState(); //锁被持有的次数
if (exclusiveCount(c) != 0 &&
getExclusiveOwnerThread() != current) //若为互斥锁 且持有锁的线程不是当前线程则返回-1;
return -1;
int r = sharedCount(c); /获取锁的共享次数
if (!readerShouldBlock() &&
r < MAX_COUNT && //锁不需要阻塞等待,共享次数小于最大值,共享次数+1
compareAndSetState(c, c + SHARED_UNIT)) {
if (r == 0) { //第一次获取读取锁 则返回1 获取成功
firstReader = current;
firstReaderHoldCount = 1;
} else if (firstReader == current) { //同一线程第二次后获取锁
firstReaderHoldCount++; //持有锁的次数++
} else { //当其他线程获取锁时会进入这个逻辑
HoldCounter rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current))
cachedHoldCounter = rh = readHolds.get();
else if (rh.count == 0)
readHolds.set(rh);
rh.count++;
}
return 1;
}
return fullTryAcquireShared(current); //当队列中首个节点是独占锁时会进入这个逻辑 这里就不分析了
}
ReentrantReadWriteLock 源码分析的更多相关文章
- 【Java并发编程】16、ReentrantReadWriteLock源码分析
一.前言 在分析了锁框架的其他类之后,下面进入锁框架中最后一个类ReentrantReadWriteLock的分析,它表示可重入读写锁,ReentrantReadWriteLock中包含了两种锁,读锁 ...
- Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析
Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...
- ReentrantReadWriteLock源码分析(一)
此处源码分析,主要是基于读锁,非公平机制,JDK1.8. 问题: 1.ReentrantReadWriteLock是如何创建读锁与写锁? 2.读锁与写锁的区别是什么? 3.锁的重入次数与获取锁的线程数 ...
- Java显式锁学习总结之五:ReentrantReadWriteLock源码分析
概述 我们在介绍AbstractQueuedSynchronizer的时候介绍过,AQS支持独占式同步状态获取/释放.共享式同步状态获取/释放两种模式,对应的典型应用分别是ReentrantLock和 ...
- ReentrantReadWriteLock源码分析笔记
ReentrantReadWriteLock包含两把锁,一是读锁ReadLock, 此乃共享锁, 一是写锁WriteLock, 此乃排它锁. 这两把锁都是基于AQS来实现的. 下面通过源码来看看Ree ...
- ReentrantReadWriteLock 源码分析以及 AQS 共享锁 (二)
前言 上一篇讲解了 AQS 的独占锁部分(参看:ReentrantLock 源码分析以及 AQS (一)),这一篇将介绍 AQS 的共享锁,以及基于共享锁实现读写锁分离的 ReentrantReadW ...
- ReentrantReadWriteLock源码分析及理解
本文结构 读写锁简介:介绍读写锁.读写锁的特性以及类定义信息 公平策略及Sync同步器:介绍读写锁提供的公平策略以及同步器源码分析 读锁:介绍读锁的一些常用操作和读锁的加锁.解锁的源码分析 写锁:介绍 ...
- 多线程之美7一ReentrantReadWriteLock源码分析
目录 前言 在多线程环境下,为了保证线程安全, 我们通常会对共享资源加锁操作,我们常用Synchronized关键字或者ReentrantLock 来实现,这两者加锁方式都是排他锁,即同一时刻最多允许 ...
- Java并发编程笔记之读写锁 ReentrantReadWriteLock 源码分析
我们知道在解决线程安全问题上使用 ReentrantLock 就可以,但是 ReentrantLock 是独占锁,同时只有一个线程可以获取该锁,而实际情况下会有写少读多的场景,显然 Reentrant ...
随机推荐
- Java生鲜电商平台-源码地址公布与思考和建议
Java生鲜电商平台-源码地址公布与思考和建议 说明:今天是承诺给大家的最后一天,我公布了github地址(QQ群里面有).诚然这个是我的计划中的事情,但是有以下几点思考请大家共勉: 1. 你下了那么 ...
- JavaScript prototype原型用法
JavaScript对象原型 所有JavaScript对象都从原型继承属性和方法. <!DOCTYPE html> <html> <meta charset=" ...
- 设计模式之设计原则 C#
成为一名资深架构师首先要懂设计模式,在懂之前,要清楚设计原则,原来我就吃过这个亏,很久以前有人问我设计原则,我是一头茫然,不是只有设计模式吗?且不知设计原则就像是写书法一样,楷体就是方正,竖道有垂露等 ...
- java的数据类型相关知识点
总结就是八个字: 数据2型,四类八种 (个人理解,仅供参考) 解析图如下: 基本数据类型: 1.逻辑类:boolean 布尔类型,它比较特殊,布尔类型只允许存储true(真)或者false(假),不可 ...
- ROW_NUMBER()实现分页
1. 在数据表基础上面添加一个自增的一列记录行数(虚拟的实际数据库不存在,不会影响数据库结构)的列当然也顺便起一个别名(我这里起了一个rowNum) 2.由于rowNum是一个虚拟的.若直接使用会报' ...
- 动态样式语言less初识
资料参考与http://lesscss.cn/ Bootstrap--(less)下载安装配置 http://lesscss.cn Less使用两种方法 (1)在客户端使用LESS--学习 编写 x. ...
- elasticsearch: 创建mapping
elasticsearch版本: 6.5.4 创建mapping PUT http://192.168.2.136:9200/index_text/_mapping/text/ { "dyn ...
- Java代码实现定时器
一 import java.util.Timer; import java.util.TimerTask; public class time { public static void main(St ...
- 【Git版本控制】Idea中设置Git忽略对某些文件的版本追踪
在Idea中有些本地文件无需与远程库同步,仅是本地使用.此时就需要将这些文件加入到Git的版本忽略中来. 设置步骤 1.搜索插件 .ignore,并安装 2.增加.gitignore文件 3.配置相应 ...
- 主成分分析(PCA)原理与实现
主成分分析原理与实现 主成分分析是一种矩阵的压缩算法,在减少矩阵维数的同时尽可能的保留原矩阵的信息,简单来说就是将 \(n×m\)的矩阵转换成\(n×k\)的矩阵,仅保留矩阵中所存在的主要特性,从 ...