AQS专题
1.背景
2.预备知识
2.1.park、unpark、interrupt、isInterrupted、interrupted方法的理解
一:park、unpark
1.park、unpark它不是Thread中的方法,而是LockSupport.park(),LockSupport是JUC中的对象;
2.park可以让线程暂停 (只有在isInterrupted状态为false的情况下才有效),unpark可以让暂停的线程继续执行;
二:interrupt、isInterrupted、interrupted
1.interrupt、isInterrupted、interrupted 它是Thread中的方法;
2.interrupt 设置一个中断标记,interrupt()方法可以让暂停的方法继续执行,通俗直观的理解是,设置打断标记后,处于暂停状态的线程就会被唤醒,如果是睡眠的就抛出中断异常;
3.isInterrupted 这个好理解就是查看当前线程的中断标记;
4.interrupted 这是一个静态方法,只能这样调用Thread.interrupted(),这个方法会返回当前interrupt状态,如果interrupt=true会将其改变为 false,反之则不成立;
系统化学习见:https://www.cnblogs.com/newAndHui/p/15939255.html

2.2.CAS无锁的理解
通俗的实现原理就是:在修改一个值时,先比较原来的值,在修改现在的值
compareAndSet(期望值,修改值);
compareAndSet(0,1);期望把1修改为0;
实现代码逻辑:

/**
* compareAndSet 做这个检查,在 set 前,先比较 prev 与当前值不一致了,next 作废,返回 false 表示失败
* <p>
* 其实 CAS 的底层是 lock cmpxchg 指令(X86 架构),在单核 CPU 和多核 CPU 下都能够保证【比较-交换】的原子性。
* 在多核状态下,某个核执行到带 lock 的指令时,CPU 会让总线锁住,当这个核把此指令执行完毕,再
* 开启总线。这个过程中不会被线程的调度机制所打断,保证了多个线程对内存操作的准确性,是原子的。
* <p>
* CAS 的特点
* 结合 CAS 和 volatile 可以实现无锁并发,适用于线程数少、多核 CPU 的场景下。
* 1.CAS 是基于乐观锁的思想:最乐观的估计,不怕别的线程来修改共享变量,就算改了也没关系,重试在执行【修改】。
* 2.synchronized 是基于悲观锁的思想:最悲观的估计,防着其它线程来修改共享变量,当前线程上锁后,其他线程阻塞等待。
* 3.CAS 体现的是【无锁并发、无阻塞并发】。
* 因为没有使用 synchronized,所以线程【不会陷入阻塞】,这是效率提升的因素之一,
* 但如果竞争激烈,可以想到重试必然频繁发生,反而频繁切换上下文,效率会受影响。
* 4.特别注意:
* 无锁情况下,但如果竞争激烈,因为线程要保持运行,需要CPU 的支持,虽然不会进入阻塞,但由于没有分到时间片,仍然会进入可运行状态,还是会导致上下文切换。
*
* @param amount
*/
private AtomicInteger balance;
@Override
public void reduce(Integer amount) {
// 不断尝试直到成功为止
while (true) {
// 修改前的值
int prev = balance.get();
// 修改后的值
int next = prev - amount;
// 执行修改 compareAndSet 使用CAS乐观锁实现
if (balance.compareAndSet(prev, next)) {
break;
}
}
// 简要写法
// balance.addAndGet(-1 * amount);
}
系统化学习见:https://www.cnblogs.com/newAndHui/p/15939255.html

3.AQS原理
1.AQS简介
AQS全称为AbstractQueuedSynchronizer(抽象队列同步器)。AQS是一个用来构建锁和其他同步组件的基础框架,
使用AQS可以简单且高效地构造出应用广泛的同步器,例如ReentrantLock、Semaphore、ReentrantReadWriteLock和FutureTask等等。
2.原理
AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。
如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,
即将暂时获取不到锁的线程加入到队列中。
3.CLH队列
CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。
AQS是将每条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node)来实现锁的分配。
4.自己写一个AQS
见博客:https://www.cnblogs.com/newAndHui/p/16686194.html
5.AQS源码解读
完美!
AQS专题的更多相关文章
- Java多线程专题4: 锁的实现基础 AQS
合集目录 Java多线程专题4: 锁的实现基础 AQS 对 AQS(AbstractQueuedSynchronizer)的理解 Provides a framework for implementi ...
- ☕【Java技术指南】「并发原理专题」AQS的技术体系之CLH、MCS锁的原理及实现
背景 SMP(Symmetric Multi-Processor) 对称多处理器结构,它是相对非对称多处理技术而言的.应用十分广泛的并行技术. 在这种架构中,一台计算机由多个CPU组成,并共享内存和其 ...
- java架构之路(多线程)AQS之ReetrantLock显示锁的使用和底层源码解读
说完了我们的synchronized,这次我们来说说我们的显示锁ReetrantLock. 上期回顾: 上次博客我们主要说了锁的分类,synchronized的使用,和synchronized隐式锁的 ...
- 大型Java进阶专题(一) 前言
前言 各位读者好,本系列为Java进阶专题,为那些有一定工作经验,做了多年业务的码农,希望突破技术瓶颈,但没有形成系统的Java只是体系,缺乏清晰的提升方法和学习路径的人,比如作者本人.该课题的是 ...
- 图灵学院JAVA互联网架构师专题学习笔记
图灵学院JAVA互联网架构师专题学习笔记 下载链接:链接: https://pan.baidu.com/s/1xbxDzmnQudnYtMt5Ce1ONQ 密码: fbdj如果失效联系v:itit11 ...
- Java多线程专题5: JUC, 锁
合集目录 Java多线程专题5: JUC, 锁 什么是可重入锁.公平锁.非公平锁.独占锁.共享锁 可重入锁 ReentrantLock A ReentrantLock is owned by the ...
- Java多线程专题6: Queue和List
合集目录 Java多线程专题6: Queue和List CopyOnWriteArrayList 如何通过写时拷贝实现并发安全的 List? CopyOnWrite(COW), 是计算机程序设计领域中 ...
- 2016年中国微信小程序专题研究报告
2016年12月29日,全球领先的移动互联网第三方数据挖掘和分析机构iiMedia Research(艾媒咨询)权威首发<2016年中国微信小程序专题研究报告>. 报告显示,82.6%手机 ...
- [.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店
一.前言 在前面专题一中,我已经介绍了我写这系列文章的初衷了.由于dax.net中的DDD框架和Byteart Retail案例并没有对其形成过程做一步步分析,而是把整个DDD的实现案例展现给我们,这 ...
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
随机推荐
- 记一下 localstorage sessionStorage cookie 不同
localStorage.sessionStorage.cookie 使用整理 下面从这几方面进行梳理 存储形式 相同点 不同点 使用方法 用途 多标签之间通讯 一.存储形式 1.localStron ...
- 关于编译告警 C4819 的完整解决方案 - The file contains a character that cannot be represented in the current code page (number). Save the file in Unicode format to prevent data loss.
引言 今天迁移开发环境的时候遇到一个问题,同样的操作系统和 Visual Studio 版本,原始开发环境一切正常,但是迁移后 VS 出现了 C4819 告警,上网查了中文的一些博客,大部分涵盖几种解 ...
- Kotlin 变量详解:声明、赋值与最佳实践指南
Kotlin 变量 变量是用于存储数据值的容器. 要创建一个变量,使用 var 或 val,然后使用等号(=)给它赋值: 语法 var 变量名 = 值 val 变量名 = 值 示例 var name ...
- Wireshark找不到接口
在管理员权限下的命令行窗口输入net start npf即可. 注意是管理员权限下的,否则会拒绝访问.
- python重拾第五天-常用模块学习
本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configpars ...
- Linux安装Redis教程
举例版本 Redis版本 5.0.4 服务器版本 Linux CentOS 7.6 64位 下载Redis 进入官网找到下载地址 https://redis.io/download 右键Downloa ...
- Linux后台运行jar文件和关闭Java程序
后台运行jar文件 Linux 运行jar包 java -jar jar文件名字.jar 这是最简单运行jar文件的命令. 特点:当前命令行窗口将被锁定,可按CTRL + C中止程序运行,或直接关闭窗 ...
- SpringBoot获取指定Resource下的文件内容
加入依赖 <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</a ...
- Solo 开发者周刊 (第9期):Dawwin首位人工智能编程师或将改变未来?
这里会整合 Solo 社区每周推广内容.产品模块或活动投稿,每周五发布.在这期周刊中,我们将深入探讨开源软件产品的开发旅程,分享来自一线独立开发者的经验和见解.本杂志开源,欢迎投稿. 好文推荐 Daw ...
- 解锁网络无限可能:揭秘微软工程师力作——付费代理IP池深度改造与实战部署指南
基于付费代理的代理IP池 项目来源 此项目为微软某个工程师构建的代理IP池,我对此进行了改造.可以用于生产环境中的爬虫项目 阅读前建议 阅读我之前发布的爬虫基础的文章,了解代理如何获取.使用等. 分为 ...