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 ...
随机推荐
- 基于OpenCV.Net投影法进行文本分块切割
假设有如下一张图,如何把其中的文本分块切割出来,比如“华普超市朝阳门店”.“2015-07-26”就是两个文本块. 做图像切割有很多种方法,本文描述一种最直观的投影检测法.先来看看什么是投影,简单来说 ...
- EF CodeFirst 使用T4模板
实用等级:★★★★★ 首先,定义一个接口,代表一个领域实体.在定义一个实体集成这个接口,面向接口编程的各种好处就不提了. /// <summary> /// 代表一个领域实体 /// &l ...
- MyBatis面试题集合,90%会遇到这些问题
1.#{}和${}的区别是什么? ${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc. ...
- Java自学-集合框架 遍历
遍历ArrayList的三种方法 步骤 1 : 用for循环遍历 通过前面的学习,知道了可以用size()和get()分别得到大小,和获取指定位置的元素,结合for循环就可以遍历出ArrayList的 ...
- 微信小程序使用函数防抖解决重复点击消耗性能问题
wxml: <view bindtap="doubleTap" bindtouchstart="touchStart" bindtouchend=&quo ...
- 对于不返回任何键列信息的 SelectCommand,不支持 DeleteCommand 的动态 SQL 生成
VS新增操作数据库出现如下报错. 原因是数据库表未添加主键 MySQL: CREATE TABLE Customer (SID integer, Last_Name ), First_Name ), ...
- odoo10学习笔记十六:定时任务
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/11189382.html 一:定义定时器数据模型 模型中定义需要用到的字段.定时方法 from odoo im ...
- Docker--部署mongodb+.netcore+nginx
前言 公司租用的阿里云的服务器,每年会更换一次,很麻烦,还容易出问题,想会不会有更方便的方式来迁移服务器,就这样接触到了docker. 参考网上的一些资料,自己琢磨了一段时间,记录下docker的部署 ...
- TiDB 学习资料
学习资料 网址 官网 https://pingcap.com/docs-cn/stable/
- python27期day05:字典、字典嵌套、作业题。
1.字典是python中的数据类型之一.唯一一种大括号{}键值对的数据. 2.存储大量的数据.将数据和数据之间进行关联. 3.通过键可以准确的找到值 4.哈希:可变数据类型就不可哈希 不可变数据类 ...