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 源码分析的更多相关文章

  1. 【Java并发编程】16、ReentrantReadWriteLock源码分析

    一.前言 在分析了锁框架的其他类之后,下面进入锁框架中最后一个类ReentrantReadWriteLock的分析,它表示可重入读写锁,ReentrantReadWriteLock中包含了两种锁,读锁 ...

  2. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...

  3. ReentrantReadWriteLock源码分析(一)

    此处源码分析,主要是基于读锁,非公平机制,JDK1.8. 问题: 1.ReentrantReadWriteLock是如何创建读锁与写锁? 2.读锁与写锁的区别是什么? 3.锁的重入次数与获取锁的线程数 ...

  4. Java显式锁学习总结之五:ReentrantReadWriteLock源码分析

    概述 我们在介绍AbstractQueuedSynchronizer的时候介绍过,AQS支持独占式同步状态获取/释放.共享式同步状态获取/释放两种模式,对应的典型应用分别是ReentrantLock和 ...

  5. ReentrantReadWriteLock源码分析笔记

    ReentrantReadWriteLock包含两把锁,一是读锁ReadLock, 此乃共享锁, 一是写锁WriteLock, 此乃排它锁. 这两把锁都是基于AQS来实现的. 下面通过源码来看看Ree ...

  6. ReentrantReadWriteLock 源码分析以及 AQS 共享锁 (二)

    前言 上一篇讲解了 AQS 的独占锁部分(参看:ReentrantLock 源码分析以及 AQS (一)),这一篇将介绍 AQS 的共享锁,以及基于共享锁实现读写锁分离的 ReentrantReadW ...

  7. ReentrantReadWriteLock源码分析及理解

    本文结构 读写锁简介:介绍读写锁.读写锁的特性以及类定义信息 公平策略及Sync同步器:介绍读写锁提供的公平策略以及同步器源码分析 读锁:介绍读锁的一些常用操作和读锁的加锁.解锁的源码分析 写锁:介绍 ...

  8. 多线程之美7一ReentrantReadWriteLock源码分析

    目录 前言 在多线程环境下,为了保证线程安全, 我们通常会对共享资源加锁操作,我们常用Synchronized关键字或者ReentrantLock 来实现,这两者加锁方式都是排他锁,即同一时刻最多允许 ...

  9. Java并发编程笔记之读写锁 ReentrantReadWriteLock 源码分析

    我们知道在解决线程安全问题上使用 ReentrantLock 就可以,但是 ReentrantLock 是独占锁,同时只有一个线程可以获取该锁,而实际情况下会有写少读多的场景,显然 Reentrant ...

随机推荐

  1. Linux软件安装——安装软件的命令

    Linux软件安装——安装软件的命令 摘要:本文主要学习了如何在Linux系统中安装.更新.卸载软件. rpm命令 rpm命令用来在Linux系统上进行软件的安装. 基本语法 安装命令: rpm -i ...

  2. QUrl的使用,特别是对含特殊字符的字符串进行 URL 格式化编码

    QUrl提取与写入参数QUrl url("www.baidu.com?a=666&b=888"); url.addQueryItem("); qDebug()&l ...

  3. 三.基础部分+asp网站搭建

    渗透测试流程:更全面地找出服务器的问题,更倾向保护 明确目标-->信息收集-->漏洞探测-->漏洞验证-->信息分析-->获取所需-->信息整理-->形成报告 ...

  4. OC-加载h5富文本的代码,并计算高度

    参考文章: 加载富文本的h5代码:https://zhidao.baidu.com/question/1510839173546014340.html 计算富文本的高度:https://zhidao. ...

  5. ptrace函数深入分析

    ptrace函数:进程跟踪. 形式:#include<sys/ptrace.h> Int ptrace(int request,int pid,int addr,int data); 概述 ...

  6. 去除数组空格 php

    public function trimArray($params){ if (!is_array($params)) return trim($params); return array_map([ ...

  7. 打开前端工程 Node Sass does not yet support your current environment: Windows 64-bit

    卸载当前sass版本,重新安装sass 打开cmd进入工程文件夹: 删除 npm uninstall --save node-sass 安装 npm install --save node-sass ...

  8. JSON Web Token 使用详解

    JWT 是什么? JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案.它是有三部分组成,示例如下,具体的讲解如下(jwt 是不会有空行的,下面只是为了显示,便使用了换行看着比较 ...

  9. angular6 使用信息提示框toast

    angular6 可以使用的toast插件有好多个,在目前来看ngx-toastr在过去一年时间的使用量和受欢迎程度可以说是一骑绝尘,如下图: 我也就选择了ngx-toastr这个插件,使用步骤如下: ...

  10. [Linux] nginx的try_files指令实现隐藏index.php的重写

    1.nginx的try_files指令 ,核心功能是替代rewrite,并且比rewrite更强大的是可以按顺序查找文件是否存在,如果文件都找不到才会执行最后的重定向解决的问题是,如果一个网站的部署是 ...