ReentrantLock 以及 AQS 实现原理
什么是可重入锁?
什么是AQS?
ReentrantLock锁的架构
AQS的等待队列
入队列
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
2)并发问题
3)挂起等待线程
- 对于Thread2来说,它的prev指向HEAD,因此会首先再尝试获取锁一次,如果失败,则会将HEAD的waitStatus值为SIGNAL,下次循环的时候再去尝试获取锁,如果还是失败,且这个时候prev节点的waitStatus已经是SIGNAL,则这个时候线程会被通过LockSupport挂起。
- 对于Thread3来说,它的prev指向Thread2,因此直接看看Thread2对应的节点的waitStatus是否为SIGNAL,如果不是则将它设置为SIGNAL,再给自己一次去看看自己有没有资格获取锁,如果Thread2还是挡在前面,且它的waitStatus是SIGNAL,则将自己挂起。
锁释放-等待线程唤起
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
- 将队头的waitStatus设置为0.
- 通过从队列尾部向队列头部移动,找到最后一个waitStatus<=0的那个节点,也就是离队头最近的没有被cancelled的那个节点,队头这个时候指向这个节点。
- 将这个节点唤醒,其实这个时候Thread1已经出队列了。
羊群效应
总结
ReentrantLock 以及 AQS 实现原理的更多相关文章
- 扒一扒ReentrantLock以及AQS实现原理
提到JAVA加锁,我们通常会想到synchronized关键字或者是Java Concurrent Util(后面简称JCU)包下面的Lock,今天就来扒一扒Lock是如何实现的,比如我们可以先提出一 ...
- ReentrantLock以及AQS实现原理
什么是可重入锁? ReentrantLock是可重入锁,什么是可重入锁呢?可重入锁就是当前持有该锁的线程能够多次获取该锁,无需等待.可重入锁是如何实现的呢?这要从ReentrantLock的一个内部类 ...
- 透过 ReentrantLock 分析 AQS 的实现原理
对于 Java 开发者来说,都会碰到多线程访问公共资源的情况,这时候,往往都是通过加锁来保证访问资源结果的正确性.在 java 中通常采用下面两种方式来解决加锁得问题: synchronized 关键 ...
- 面经手册 · 第17篇《码农会锁,ReentrantLock之AQS原理分析和实践使用》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 如果你相信你做什么都能成,你会自信的多! 千万不要总自我否定,尤其是职场的打工人.如 ...
- 并发编程学习笔记(5)----AbstractQueuedSynchronizer(AQS)原理及使用
(一)什么是AQS? 阅读java文档可以知道,AbstractQueuedSynchronizer是实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量.事件,等等)提供一个框架, ...
- AQS工作原理分析
AQS工作原理分析 一.大致介绍1.前面章节讲解了一下CAS,简单讲就是cmpxchg+lock的原子操作:2.而在谈到并发操作里面,我们不得不谈到AQS,JDK的源码里面好多并发的类都是通过Sy ...
- 从ReentrantLock看AQS (AbstractQueuedSynchronizer) 运行流程
从ReentrantLock看AQS (AbstractQueuedSynchronizer) 运行流程 概述 本文将以ReentrantLock为例来讲解AbstractQueuedSynchron ...
- AQS实现原理
AQS实现原理 AQS中维护了一个volatile int state(共享资源)和一个CLH队列.当state=1时代表当前对象锁已经被占用,其他线程来加锁时则会失败,失败的线程被放入一个FIFO的 ...
- ReentrantLock 与 AQS 源码分析
ReentrantLock 与 AQS 源码分析 1. 基本结构 重入锁 ReetrantLock,JDK 1.5新增的类,作用与synchronized关键字相当,但比synchronized ...
随机推荐
- Archlinux 的U盘自动装载(三)udevil
U盘的自动装载方法,目前我已经使用过以下几种方法: udev 规则 基于 udev 规则的 Shell script udisks 以及 udisks2 结果,总是存在这样那样的小问题.例如,文件名乱 ...
- springMVC中文乱码问题解决
1:表单提交controller获得中文参数后乱码解决方案 注意: jsp页面编码设置为UTF-8 form表单提交方式为必须为post,get方式下面spring编码过滤器不起效果 <%@ ...
- .Net Core迁移到MSBuild平台(二)
一.前言 在上一篇文章.Net Core迁移到MSBuild的多平台编译问题中,简单的讲了下新的项目配置文件中的节点配置,这篇我将用一些例子来详细讲下从project.json迁移到msbuild过程 ...
- javascript写贪吃蛇游戏(20行代码!)
<!doctype html> <html> <body> <canvas id="can" width="400" ...
- ubuntu firefox上看视频,安装flash啊
这是针对于直接硬盘安装的linux系统: u盘安装选择了安装第三方软件的话就不会存在这种问题 flash的安装其实也不是很难的,有点耐心就ok了 总结一下: 1:肯定是下载最新版的flash啦,注意看 ...
- Mysql 保留最新的10条数据
Mysql每天执行计划,保留最新的10条数据,其余的删除 1.Mysql 保留最新的10条数据 sql语句: DELETE tb FROM tbname AS tb,( SELECT id FROM ...
- PHP的简单易懂文件管理,可实现基本功能
我们利用的是嵌入PHP代码和ajax结合的方式,首相想到的是利用遍历文件的方式找出分件下的目录和文件,并且找到它们的路径,使用 dirname取上级目录, basename从完整路径中取文件名,其中最 ...
- media query(媒体查询)和media type(媒体类型)
media type(媒体类型)是css 2中的一个非常有用的属性,通过media type我们可以对不同的设备指定特定的样式,从而实现更丰富的界面.media query(媒体查询)是对media ...
- Office 365开发环境概览
本文于2017年3月26日首发于LinkedIn,原文链接请参考这里 本系列文章已经按照既定计划在每周更新,此前的几篇文章如下 Office 365 开发概览系列文章和教程 Office 365开发概 ...
- 在linux下使用百度ueditor编辑器上传图片
百度ueditor编辑器虽然强大,但是也有不足的地方.如果对ueditor流程不是很熟悉可以说走的弯路比较多,费力不讨好.下面呢,就是要解决ueditor遇到的问题. 用ueditor上传图片遇到的问 ...