java源码-ReentrantLock源码分析-1
ReentrantLock 继承于lock是比较常用的独占锁,接下来我们来分析一下ReentrantLock源码以及接口设计:
Sync是ReentrantLock的内部静态抽象类继承AbstractQueuedSynchronizer类,ReentrantLock类部还有两个类FairSync(公平锁)跟NonfairSync(非公平锁)类实现Sync;
ReentrantLock默认内部是构建非公平锁,也可以制定使用公平锁跟非公平锁,
当调用lock()方法时,下面分析公平锁跟非公平区别:
lock()具体指向内部实例化的Sync对象
公平锁lock()方法直接调用acquire(1)直接尝试获取一次锁(第一次由于锁被抢占,加入队列时判断是否锁已经释放),如果失败后则加入队列
非公平锁,首先通过cas强行获取一次锁,失败后在调用acquire(1)尝试获取锁失败后加入队列
tryAcquire(1)方法实现也不同 非公平锁最终会调用Sync对象的nofairTryAcquire()方法,当state=0代表没有锁占用,此时会调用cas强行占用锁,
这时候如果同时新加入的线程抢占锁失败,导致后加入的锁进入队列,这时候体现无序不公平。
公平锁首先hasQueuedPredecessors()判断没有前驱节点代表是head节点然后再获取锁,
不管是公平锁还是非公平锁都支持重入锁,直接把state计数+1;
acquireQueued()方法主要左右是将实例化当前线程绑定Node节点加入队列并修改前驱节点Node的waitStatus为SIGNAL,同时并挂起当前节点;
首先new Node节点绑定线程,独占锁默认nextWaiter为空,如果存在tail节点然后通过cas添加tail节点,如果不存在会调用enq(node)方法初始化head节点
此时再次判断tail节点是否为空,如果为空然后cas添加一个空节点然后进入空转,下次循环再cas添加节点都tail节点,这里有人会疑问为什么会添加一个空Node节点而且并没有
绑定线程?
首先获取前驱节点,如果前驱节点是头节点,然后尝试获取一下锁,如果成功则设置当前node为head节点然后将前驱节点移除队列;
如果前驱节点不是头节点或者获取锁失败,此时进入shouldParkAfterFailedAcquire()方法
如果前驱节点是SIGNAL=-1则表示是可以挂起线程,等待前驱节点唤醒,如果前驱节点是刚才new Node() 的话
ws=0此时将会cas修改状态为SIGNAL,然后返回false然后进入自旋,再次进入此方法则再挂起当前线程。最后形成的链表处tail节点都是signal状态切线程状态都是挂起,
等待释放然后唤起header节点的next节点。
java源码-ReentrantLock源码分析-1的更多相关文章
- Java并发编程-ReentrantLock源码分析
一.前言 在分析了 AbstractQueuedSynchronier 源码后,接着分析ReentrantLock源码,其实在 AbstractQueuedSynchronizer 的分析中,已经提到 ...
- Java并发之ReentrantLock源码解析(二)
在了解如何加锁时候,我们再来了解如何解锁.可重入互斥锁ReentrantLock的解锁方法unlock()并不区分是公平锁还是非公平锁,Sync类并没有实现release(int arg)方法,这里会 ...
- Java并发之ReentrantLock源码解析(四)
Condition 在上一章中,我们大概了解了Condition的使用,下面我们来看看Condition再juc的实现.juc下Condition本质上是一个接口,它只定义了这个接口的使用方式,具体的 ...
- Java并发编程 ReentrantLock 源码分析
ReentrantLock 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. 这个类主要基于AQS(Abst ...
- java源码-ReentrantLock源码分析-2
继续上篇ReentrantLock分析如何唤醒线程: 当调用lock.unlock()方法最终调用AQS类中的release方法,开始释放锁 tryRelease(1)方法在Sync对象中实现,首先会 ...
- Java并发之ReentrantLock源码解析(三)
ReentrantLock和BlockingQueue 首先,看到这个标题,不要怀疑自己进错文章,也不要怀疑笔者写错,哈哈.本章笔者会从BlockingQueue(阻塞队列)的角度,看看juc包下的阻 ...
- Java并发之ReentrantLock源码解析(一)
ReentrantLock ReentrantLock是一种可重入的互斥锁,它的行为和作用与关键字synchronized有些类似,在并发场景下可以让多个线程按照一定的顺序访问同一资源.相比synch ...
- Java并发系列[5]----ReentrantLock源码分析
在Java5.0之前,协调对共享对象的访问可以使用的机制只有synchronized和volatile.我们知道synchronized关键字实现了内置锁,而volatile关键字保证了多线程的内存可 ...
- Java并发编程之ReentrantLock源码分析
ReentrantLock介绍 从JDK1.5之前,我们都是使用synchronized关键字来对代码块加锁,在JDK1.5引入了ReentrantLock锁.synchronized关键字性能比Re ...
随机推荐
- 配置lnmp时出现“file not found?
问题: 昨天测试并搭建lnmp架构,在测试过程中,挂载好测试环境时在浏览器上测试网站出现“file not found",使用命令curl时也出现”file not found", ...
- 认识并初步应用GitHub
好好学习,天天向上 一.这是一个简单的开头 GIT的地址 https://github.com/Notexcellent GIT的用户名 Notexcxllent 学号后五位 82405 博客地址 h ...
- Summer training #6
A:水.看0多还是1多就行 B:模拟二进制运算 ,,卡了好久 不应该 #include <bits/stdc++.h> #include <cstring> #include ...
- 本地phpmyadmin 访问远程数据库服务器
第一步:打开/phpmyadmin/libraries 目录 第二步:修改config.default.php 文件(linux下可用vim编辑,FreeBSD下可用vi或是ee编辑)找到“All ...
- 第六章 组件 63 组件传值-父组件向子组件传值和data与props的区别
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- BZOJ3589 动态树[树剖/暴力/容斥]
操作0,显然直接线段树解决. 操作1,瓶颈在于重叠的链只算一次.在线段树上来看,如果一个区间被覆盖了,那么只算这个区间,子树里面也就不管了. 考虑对节点打标记来表示是否覆盖.但是,如果统一打完之后,并 ...
- Vue-指令补充、过滤器、计数器属性、监听属性
vue实例成员: el | template |data | methods watch 监听事件| computed 计数属性使用 | filters过滤器 | props 父传子 componen ...
- Linux( Ubantu ) 的简单使用
1.Linux常用的快捷键 Ctrl + Alt+ T --打开终端 Ctrl + Shift + C --复制 Ctrl + Shift + V --粘贴 Ctrl + Shift + A --光标 ...
- [Algorithm] Area of polygon
How to calculate the area of polygon. For a triangle like: We can calculate the area: function cross ...
- python爬虫添加请求头
request import requests headers = { # 'Accept': 'application/json, text/javascript, */*; q=0.01', # ...