ReentrantLock梳理和总结
一、ReentrantLock的lock()梳理
首先贴下lock()源码调用时序图:
源码:
- 首先通过cas抢占锁
- 如果抢占失败,则执行acquire()方法
- tryAcquire方法:再抢占一次锁。会走到nofairTryAcquire方法,nofairTryAcquire方法的主要作用是再次抢占锁。分为两种情况,state为0和state不为0。state为0表示没有重入,state不为0且当前抢占锁的线程为当前线程,表示重入了锁,state需要+1。
- addWaiter方法:如果步骤1抢占锁失败,则需要将当前线程包装成Node,放到aqs同步队列的尾部。
- acquireQueued:在同步队列中抢占锁,只有head节点才能抢占锁,也就是说,在同步队列中,节点抢占锁的顺序是由链表的前往后。acquireQueued方法是包含一个死循环的,出口是只能是当前节点是头节点并抢到了锁,否则就挂起线程。
上述方法的具体代码我就不贴了,之前的文章分析过。 直接贴上之前文章的图解吧:
二、ReentrantLock的unlock()梳理
unlock方法主要做了两个动作:
- 释放锁,即state-1,并且exclusiveOwnerThread属性设置为null。
- 唤醒离head节点最近的waitStatus<=0的节点线程
三、加锁和释放锁流程图
四、公平锁和非公平锁的区别
- 非公平锁会先进行一次cas抢占锁,没抢占到才加入aqs队列。
- 公平锁,则会判断aqs队列当前节点是否有前驱节点,如果返回true,则表示有线程比当前线程更早地请求获取锁,因此需要等待前驱线程获取并释放锁之后才能继续获取锁。
五、在队列同步器中,同步队列为什么是双向链表,而等待队列是单链表?
在《Java并发编程的艺术》一书中有这样一段话:
在队列同步器中,头节点是成功获取到同步状态的节点,而头节点的线程释放了同步状态后,将会唤醒其他后续节点,后继节点的线程被唤醒后需要检查自己的前驱节点是否是头节点,如果是则尝试获取同步状态。
所以为了能让后继节点获取到其前驱节点,同步队列便设置为双向链表,而等待队列没有这样的需求,就为单链表。
六、请简述AQS原理
简述AQS原理
ReentrantLock梳理和总结相关推荐
- 通俗易懂的ReentrantLock,不懂你来砍我
前言 自己开的坑,跪着也要填完,欢迎来到Java并发编程系列第五篇ReentrantLock,文章风格依然是图文并茂,通俗易懂,本文带读者们深入理解ReentrantLock设计思想. 认识下Reen ...
- 这篇 ReentrantLock 看不懂,加我我给你发红包
来自:Java建设者 回答一个问题 在开始本篇文章的内容讲述前,先来回答我一个问题,为什么 JDK 提供一个 synchronized 关键字之后还要提供一个 Lock 锁,这不是多此一举吗?难道 J ...
- Java Review - 并发编程_独占锁ReentrantLock原理源码剖析
文章目录 Synchronized vs ReentrantLock ReentrantLock概述 获取锁 void lock() 非公平锁的实现代码 非公平锁是如何体现的? 公平锁是怎么实现公平的 ...
- java要频繁调用容器时_Java最常见的200+面试题及自己梳理的答案--面试必备(一)...
昨天在今日头条上看到一份所谓经常面别人的TL梳理的面试题,看着比较完善,但是,没有对应的答案,自己看着研究学习了下,顺带梳理下答案.主要包括以下模块:Java基础.容器.多线程.反射.对象拷贝.Jav ...
- 万字图文 | 聊一聊 ReentrantLock 和 AQS 那点事(看完不会你找我)
前言 AbstractQueuedSynchronizer(AQS)是 Java 并发编程中绕不过去的一道坎,JUC 并发包下的 Lock.Semaphore.ReentrantLock 等都是基于 ...
- 跟着刚哥梳理java知识点——多线程(十六)
创建多线程 第一种方式: ① 继承:继承Thread. ② 重写:重写Thread类的run()方法 ③ 创建:创建一个子类的对象 ④ 调用:调用线程的start()方法,启动此线程,调用run()方 ...
- 打通JAVA与内核系列之一ReentrantLock锁的实现原理
简介:写JAVA代码的同学都知道,JAVA里的锁有两大类,一类是synchronized锁,一类是concurrent包里的锁(JUC锁).其中synchronized锁是JAVA语言层面提供的能力, ...
- java内存泄漏定位和解决,学习路线+知识点梳理
分享第一份Java基础-中级-高级面试集合 Java基础(对象+线程+字符+接口+变量+异常+方法) Java中级开发(底层+Spring相关+Redis+分布式+设计模式+MySQL+高并发+锁+线 ...
- 资料搜集-JAVA系统的梳理知识6-JAVA多线程
点击关注[公众号](#公众号 "公众号")及时获取笔主最新更新文章,并可免费领取本文档配套的<Java 面试突击>以及 Java 工程师必备学习资源.<!-- T ...
- Android 知识梳理目录 - 好吧,这是一个很“干,安卓系列学习进阶视频
============== 2.1 Activity 知识梳理 Activity 知识梳理(1) - Activity 生命周期 Activity 知识梳理(2) - Activity 栈 Acti ...
最新文章
- mysql 移植 azure_初码-Azure系列-记一次MySQL数据库向Azure的迁移
- hdu3706基础的单调队列
- 史上最详细阿里云服务器上Docker部署War包项目 实战每一步都带详细图解!!!
- 十三、写了两年多Python文章的我,带你走进Python数据分析
- PHPstorm相同变量标识
- 1009 说反话 (20 分)(c语言)
- Windows Workflow Foundation - [介绍及相关资源]
- 论文浅尝 | 基于动态记忆的原型网络进行元学习以实现少样本事件探测
- 软件版本号命名规范_软件发布版本介绍
- java中怎么删除多表连接_在Java中从多个列表中合并和删除重复的最佳方式
- mongoDB配制及学习
- django在linux一直跑
- linux运行j2me,Linux下用Eclipse搭建J2me开发环境过程
- Virtualbox安装Windows7虚拟机
- jsp中点击验证码刷新验证码
- TF卡用FAT32还是NTFS?
- C++ Primer Plus 学习笔记(十一)
- php上传图片到七牛云,PHP拖拽上传图片到七牛云
- matlab绘制垂线(x轴或y轴)
- ios禁止屏幕旋转的几种方法
热门文章
- 机器学习- 吴恩达Andrew Ng Week4 神经网络Neural Networks知识总结
- 算法:Design Circular Deque(设计一个双端队列)
- strdup linux,内存管理 – Linux内核API kstrdup
- linux拷贝数据库文件夹,手工拷贝数据库文件建立新的数据库实例过程
- 可视化修改SQL服务器名字,修改sql server服务器名称
- oracle binlog同步,系统设计 | 通过Binlog来实现系统间数据同步
- vscode 配置python_VSCode配置Python版本
- EDSR:Enhanced Deep Residual Networks for Single Image Super-Resolution
- 推荐给初学LSTM或者懂个大概却不完全懂的人
- 数据库基础(5)1NF,2NF,3NF,BCNF 四大范式的定义和判别