Java并发——ReentrantLock类源码阅读
ReentrantLock内部由Sync类实例实现。

Sync类定义于ReentrantLock内部。

Sync继承于AbstractQueuedSynchronizer。
AbstractQueuedSynchronizer继承于AbstractOwnableSynchronizer。
AbstractOwnableSynchronizer类中只定义了一个exclusiveOwnerThread变量,表示当前拥有的线程。

除了Sync类,ReentrantLock内部还定义了两个实现类。

NonfairSync是非公平锁。FairSync 是公平锁。
ReentrantLock两个构造方法如下:

ReentrantLock的lock方法

非公平锁的lock方法

compareAndSetState方法是一个CAS方法。该方法尝试去更新对象内的一个变量。变量期望是0,更新为1。
若更新成功,则将exclusiveOwnerThread变量设置为当前线程。然后lock方法会立刻返回。
若更新不成功,则调用acquire(1)。

acquire方法中首先调用tryAcquire()再次尝试更新。
非公平锁的tryAcquire()方法如下:

非公平锁的tryAcquire()方法内部调用nonfairTryAcquire方法如下:

若tryAcquire()方法再次尝试不成功。则首先会调用addWaiter()方法,将当前线程加入等待队列。addWaiter方法返回一个Node节点。

返回节点后,acquireQueued(node,1)会再次尝试去做更新。

若还是无法更新,则通过parkAndCheckInterrupt将线程挂起。

ReentrantLock的unlock方法

查看release()方法。

若队列的head不为空,且head的等待状态不为0,则调用unparkSuccessor()方法。
unparkSuccessor()方法如下:

使node的next从后向前遍历,获取到队列中最前面的一个waitStatus小于0的线程。然后将节点上的线程继续执行。
Java并发——ReentrantLock类源码阅读的更多相关文章
- 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分
这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...
- java 并发编程——Thread 源码重新学习
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- 《java.util.concurrent 包源码阅读》 结束语
<java.util.concurrent 包源码阅读>系列文章已经全部写完了.开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边 ...
- Java集合---Array类源码解析
Java集合---Array类源码解析 ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...
- java.lang.Void类源码解析_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 在一次源码查看ThreadGroup的时候,看到一段代码,为以下: /* * @throws NullPointerEx ...
- java并发系列(四)-----源码角度彻底理解ReentrantLock(重入锁)
1.前言 ReentrantLock可以有公平锁和非公平锁的不同实现,只要在构造它的时候传入不同的布尔值,继续跟进下源码我们就能发现,关键在于实例化内部变量sync的方式不同,如下所示: /** * ...
- Java并发——结合CountDownLatch源码、Semaphore源码及ReentrantLock源码来看AQS原理
前言: 如果说J.U.C包下的核心是什么?那我想答案只有一个就是AQS.那么AQS是什么呢?接下来让我们一起揭开AQS的神秘面纱 AQS是什么? AQS是AbstractQueuedSynchroni ...
- Java集合---Arrays类源码解析
一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Primitive(8种基本类型)和Object两大类. 基本类型:采用调优的快速排序: 对象类型: ...
- java.lang.system 类源码解读
通过每块代码进行源码解读,并发现源码使用的技术栈,扩展视野. registerNatives 方法解读 /* register the natives via the static initializ ...
随机推荐
- eclipse 代码中突然出现特殊字符
在写代码的时候,不知道点到了 eclipse 的哪个属性,代码中就出现了一些特殊字符,也不能删除. 请问,在 eclipse 中该怎么设置,才能将这些字符去掉. 如下图所示: 解决方法: 选择Wind ...
- bzoj3796
好像已经很久没有做后缀数组的题目,导致这种题一开始没想出来看到公共子串肯定想到后缀数组吧,但我都忘了最长公共子串怎么求了重要的性质:最长公共子串=max(h[i])名次相邻的两个后缀要分别属于s1,s ...
- c语言诊断_断言库函数#include<assert.h>
诊断<assert.h> assert #include <assert.h> void assert(int exp); assert宏用于为程序增加诊断功能.当asser ...
- Android 开发性能优化之SparseArray(三)
SparseArray是android里为<Interger,Object>这样的Hashmap而专门写的class,目的是提高效率,其核心是折半查找函数(binarySearch) pr ...
- 【JS】Beginner3 & 4 & 5 & 6:Maths & Logic & Conditonal & Looping
1.number operator () * / + - 2.logic make decisions in code compare values to produce a boolean valu ...
- x&-x
x&-x的值是啥米呢?列入10 二进制位 1010为2 1011则为 1,1000为8,就是一个整数对应的二进制数中1所在最低位的权值. 在树状数组中很有用
- bzoj 1879 [Sdoi2009]Bill的挑战(状压DP)
Description Input 本题包含多组数据. 第一行:一个整数T,表示数据的个数. 对于每组数据: 第一行:两个整数,N和K(含义如题目表述). 接下来N行:每行一个字符串. Output ...
- Storm系列(十)聚流示例
功能:将多个数据源的数据汇集到一个处理单元进行集中分类处理: 入口类TestMain 1 ; i < size; i++) { 31 content += input ...
- 【Java基础】Java异常的一些总结
什么是异常 异常是指程序运行可能出现的不能正常继续的情况,也可以理解为程序出现了不在预期范围内的一些情况,都可以称之为异常. 异常的分类 所有的异常类是从java.lang.Exception类继承的 ...
- HW1.1
public class Solution { public static void main(String[] args) { System.out.println("Welcome to ...