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. C 函数声明、函数参数

    参考连接:https://www.runoob.com/cprogramming/c-functions.html 局部变量与全局变量在内存中的储存方式 全局变量保存在内存中的全局储存区中,占用静态的 ...

  2. Flask笔记:文件上传

    文件上传 enctype:在HTML中的form表单中form标签默认是`enctype="application/x-www-form-urlencoded"`,在文件上传时需要 ...

  3. Codeforces 1256A 1257A

    题目链接:https://codeforces.com/problemset/problem/1256/A A. Payment Without Change time limit per test ...

  4. ASP.NET Core系列:JWT身份认证

    1. JWT概述 JSON Web Token(JWT)是目前流行的跨域身份验证解决方案. JWT的官网地址:https://jwt.io JWT的实现方式是将用户信息存储在客户端,服务端不进行保存. ...

  5. React入门(二)

    组件的生命周期 概念:在组件创建.到加载到页面运行.以及组件被销毁的过程中伴随的事件.组件的生命周期是指在组件的特定时期触发的事件. 组件的生命周期分为三个部分: 组件创建阶段:只执行一次 compo ...

  6. windows 如何cmd启动redis

    运行cmd 然后到redis路径 运行命令: redis-server redis.windows.conf

  7. 多任务学习Multi-task-learning MTL

    https://blog.csdn.net/chanbo8205/article/details/84170813 多任务学习(Multitask learning)是迁移学习算法的一种,迁移学习可理 ...

  8. 其他综合-VMware 从模板机快速克隆多台

    VMware 从模板机快速克隆多台 1.实验描述 通过 CentOS 7.6 的模板机快速克隆,为实现搭建其他项目而提供干净的实验平台. [基于此文章的环境]点我快速打开文章 2.实验环境 使用软件的 ...

  9. HDU 1072 Nightmare 题解

    Nightmare Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  10. Invitation Cards POJ - 1511

    题目链接:https://vjudge.net/problem/POJ-1511 思路:题目意思就是,从1出发到所有城市,再从所有城市回到1的最短时间. 那么我们只要正跑一次图,然后反向存边,再跑一次 ...