AQS.addWaiter
当tryAcquire方法获取锁失败以后,则会先调用addWaiter将当前线程封装成Node.
入参mode表示当前节点的状态,传递的参数是Node.EXCLUSIVE,表示独占状态。意味着重入锁用到了AQS的独占锁功能
1. 将当前线程封装成Node
2. 当前链表中的tail节点是否为空,如果不为空,则通过cas操作把当前线程的node添加到AQS队列
3. 如果为空或者cas失败,调用enq将节点添加到AQS队列
private Node addWaiter(Node mode) { Node node = new Node(Thread.currentThread(), mode);//把当前线程封装为Node Node pred = tail; //tail是AQS中表示同比队列队尾的属性,默认是null if (pred != null) {//tail不为空的情况下,说明队列中存在节点 node.prev = pred;//把当前线程的Node的prev指向tail if (compareAndSetTail(pred, node)) {//通过cas把node加入到AQS队列,也就是设置为tail pred.next = node;//设置成功以后,把原tail节点的next指向当前node return node; } } enq(node);//tail=null,把node添加到同步队列 return node;
}
enq
enq就是通过自旋操作把当前节点加入到队列中
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; } } }
}
图解分析
假设3个线程来争抢锁,那么截止到enq方法运行结束之后,或者调用addwaiter方法结束后,AQS中的链表结构图
AQS.addWaiter相关推荐
- Java中的CAS以及AQS实现原理
Java中的CAS实现原理 什么是CAS? 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令. 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将 ...
- 啰里吧嗦CountDownLatch
java.util.concurrent Class CountDownLatch 目录 CountDownLatch 是什么 CountDownLatch是一个同步工具类,它允许一个或多个线程一直等 ...
- java aqs源码_Java-AQS源码详解(细节很多!)
ReentrantLock调用lock()时时序图: addWaiter方法: enq方法:自旋 它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用 ...
- JUC AQS ReentrantLock源码分析
Java的内置锁一直都是备受争议的,在JDK 1.6之前,synchronized这个重量级锁其性能一直都是较为低下,虽然在1.6后,进行大量的锁优化策略,但是与Lock相比synchronized还 ...
- Java并发同步器AQS
AQS是AbstractQueuedSynchronizer的简写,中文名应该叫抽象队列同步器(我给的名字,哈哈),出生于Java 1.5. 一.什么是同步器 多线程并发的执行,之间通过某种 共享 状 ...
- 扔掉源码,15张图带你彻底理解java AQS
java中AQS是AbstractQueuedSynchronizer类,AQS依赖FIFO队列来提供一个框架,这个框架用于实现锁以及锁相关的同步器,比如信号量.事件等. 在AQS中,主要有两部分功能 ...
- 源码级深挖AQS队列同步器
我们知道,在java中提供了两类锁的实现,一种是在jvm层级上实现的synchrinized隐式锁,另一类是jdk在代码层级实现的,juc包下的Lock显示锁,而提到Lock就不得不提一下它的核心队列 ...
- Java高并发编程基础之AQS
引言 曾经有一道比较比较经典的面试题"你能够说说java的并发包下面有哪些常见的类?"大多数人应该都可以说出 CountDownLatch.CyclicBarrier.Sempah ...
- 1.5w字,30图带你彻底掌握 AQS!
前言 AQS( AbstractQueuedSynchronizer )是一个用来构建锁和同步器(所谓同步,是指线程之间的通信.协作)的框架,Lock 包中的各种锁(如常见的 ReentrantLoc ...
最新文章
- 点击文字弹出一个DIV层窗口代码
- 记一次JVM Metaspace溢出排查
- Leetcode 160.相交链表
- lockfree buffer test
- mysql 查询 distinct_MYSQL查询数据(二)SELECT | DISTINCT
- UTF-8笔记170330
- 1.3 安装Oracle遇到的问题-yum更新配置
- HDU 4911 Inversion 树状数组求逆序数对
- [2021-09-04 AtCoder Beginner Contest 217] 题解
- vue swiper循环播放无效解决
- 案例49-crm练习获取客户列表带有分页和筛选功能
- kibana数据导入导出_MySQL数据库批量导出和导入查询数据
- hdu 2586 (LCA)
- 问题 F: Search Problem (III)
- 【jQuery笔记Part4】02-jQuery微博案例
- 华为正式发布鸿蒙OS操作系统,分布式架构首次用于终端
- idea tomcat 发布web工程全过程
- java编译命令是什么_java编译命令,java的编译命令是什么?
- ubuntu-PyV8安装(网盘资源)
- linux给普通用户添加管理员权限,linux 赋予普通用户管理员权限
热门文章
- Google Maps JavaScript API V3 根据地址 加载地图
- 让Entity Framework支持MySql数据库
- flash 编程技巧应用 原创
- Redis|Sentinel 高可用架构
- Java消息中间件的概述与JMS规范
- BZOJ1798: [Ahoi2009]Seq 维护序列seq
- Linux网络基本配置
- (LINQ 学习系列)(8)Linq教程实例: 事务处理
- [导入]Vista的屏幕截图小工具:Snipping Tool
- 【Apache JMeter】JMeter接口压测实例