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# .NET Framework 版本确定

    关于.NET Framework 版本信息这里做个介绍: 1. 编译时,工程的目标的 .NET Framework 版本 同样的代码,我先选择.net 4.0,就发现有语法错误,原因是4.0版本还没提 ...

  2. postman强大的团队协作功能

    今天无意在调项目的接口 ,使用的postman工具 ,自己写的接口信息,只能自己看 ,感觉有点不方便,如果一个公司多名测试,如果一个人写接口信息,大家都能用,就会很节约时间 所以团队协作的功能就诞生了 ...

  3. CSS 选择器大全

    在CSS中,选择器是用于选择要设置样式的元素的模式. 选择器 例子 描述 .class .intro 选择class=“intro”的所有元素 #id #firstname 选择id=“firstna ...

  4. Linux查看系统当前登录用户的命令,top命令看到users有多个用户登录

    Linux查看系统当前登录用户的命令,top命令看到users有多个用户登录 作为系统管理员,top命令看到users有多个用户登录,会需要查看下是否被黑客进入了. 实战例子:top命令:top - ...

  5. SAP MM 公司间STO里外向交货单与内向交货单里序列号对应关系

    SAP MM 公司间STO里外向交货单与内向交货单里序列号对应关系 笔者所在的A项目,后勤模块里有启用HU管理,序列号管理,批次管理等功能,以实现各个业务场景下的追溯. 公司间转储订单流程里,如果是整 ...

  6. 英语AquilariaCrassna奇楠沉香

    越南奇楠沉香Aquilaria crassna是瑞香科沉香属植物. 奇楠香被喻为沉香中的钻石,其与身俱来的香气,淡雅宜人,汇集天地阴阳五行之气,而成为唯一能通三界之香品.长久以来,它被视为一种珍贵罕有 ...

  7. java并发查询数据

    并发服务 package com.springboot_android.thread; import com.project_entity.bean.DeviceRecrodBean; import ...

  8. Struts2 Action的3种创建方式

    Action是Strut2的核心内容,相当于Servlet,用于处理业务. Action是一个Java类,直接新建Java类即可. Action有3种实现方式. 1.使用POJO,设置成员变量,写对应 ...

  9. 从html富文本中提取纯文本

    其实从html富文本中提取纯文本很简单,富文本基本上是使用html标签给文本加上丰富多彩的样式. 所以只需要将富文本字符串中的“<.....>”标签剔除,即可得到纯文本.我们可以使用正则表 ...

  10. centos7 apache 配置ssl

    因为小程序后台服务器需要是https的,所以这两天赶紧百度了一波什么是https以及怎么将服务器升级为https.虽然网上教程很多但因具体环境可能有差异导致一路遇坑,摸爬滚打了两天终于弄好了.遂记下一 ...