![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
CAS 原理、死锁问题、AQS 框架、
文章平均质量分 91
CAS 原理、死锁问题、AQS 框架、final 关键字和“不变性”
Ssssongsmith 奕飞
这个作者很懒,什么都没留下…
展开
-
AQS 的内部原理是什么样的?
AQS 内部原理解析我们对 AQS 进行内部原理解析的话需要抓住重点,因为 AQS 的内部比较复杂,代码很长而且非常不容易读懂,如果我们一上来就一头扎进去读源码,是很难完全掌握它的。所以在本课时中,我们把 AQS 最核心的三个部分作为重点提炼出来,由这三个部分作为切入点,打开 AQS 的大门。是哪三大部分呢?AQS 最核心的三大部分就是状态、队列和期望协作工具类去实现的获取/释放等重要方法。我们就从这三个部分出发,分别展开讲解。state 状态第一个要讲解的是状态 state,如果我们的 AQS 想原创 2021-02-28 21:41:17 · 216 阅读 · 0 评论 -
-AQS 在 CountDownLatch 等类中的应用原理是什么?
分享内容: AQS 在 CountDownLatch 类中的应用原理,即在 CountDownLatch 中如何利用 AQS 去实现 CountDownLatch 自己的线程协作逻辑的。本课时会包含一定的源码分析。AQS 用法我们先讲一下 AQS 的用法。如果想使用 AQS 来写一个自己的线程协作工具类,通常而言是分为以下三步,这也是 JDK 里利用 AQS 类的主要步骤:第一步,新建一个自己的线程协作工具类,在内部写一个 Sync 类,该 Sync 类继承 AbstractQueuedSynchr原创 2021-02-26 21:51:00 · 157 阅读 · 0 评论 -
为什么需要 AQS?AQS 的作用和重要性是什么?
AQS 的重要性我们先来介绍一下 AQS(AbstractQueuedSynchronizer)的重要性,来看看 AQS 被用在了哪些类里面。如图所示,AQS 在 ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch、ThreadPoolExcutor 的 Worker 中都有运用(JDK 1.8),AQS 是这些类的底层原理。而以上这些类,很多都是我们经常使用的类,大部分我们在前面课时中也已经详细介绍过,所以说 JUC 包里很多原创 2021-02-24 12:56:16 · 632 阅读 · 0 评论 -
70-有哪些解决死锁问题的策略?
线上发生死锁应该怎么办如果线上环境发生了死锁,那么其实不良后果就已经造成了,修复死锁的最好时机在于“防患于未然”,而不是事后补救。就好比发生火灾时,一旦着了大火,想要不造成损失去扑灭几乎已经不可能了。死锁也是一样的,如果线上发生死锁问题,为了尽快减小损失,最好的办法是保存 JVM 信息、日志等“案发现场”的数据,然后立刻重启服务,来尝试修复死锁。为什么说重启服务能解决这个问题呢?因为发生死锁往往要有很多前提条件的,并且当并发度足够高的时候才有可能会发生死锁,所以重启后再次立刻发生死锁的几率并不是很大,当我原创 2021-02-19 14:58:37 · 504 阅读 · 2 评论 -
-你知道什么是 CAS 吗?
CAS 简介CAS 其实是我们面试中的常客,因为它是原子类的底层原理,同时也是乐观锁的原理,所以当你去面试的时候,经常会遇到这样的问题“你知道哪些类型的锁”?你可能会回答“悲观锁和乐观锁”,那么下一个问题很有可能是问乐观锁的原理,也就是和 CAS 相关的问题,当然也有可能会继续深入问你 CAS 的应用场景或者是缺点等问题。首先我们来看一下 CAS 是什么,它的英文全称是 Compare-And-Swap,中文叫做“比较并交换”,它是一种思想、一种算法。在多线程的情况下,各个代码的执行顺序是不能确定的,原创 2021-02-18 10:38:11 · 3252 阅读 · 1 评论 -
69-如何用命令行和代码定位死锁?
在此之前,我们介绍了什么是死锁,以及死锁发生的必要条件。当然,即便我们很小心地编写代码,也必不可免地依然有可能会发生死锁,一旦死锁发生,第一步要做的就是把它给找到,因为在找到并定位到死锁之后,才能有接下来的补救措施,比如解除死锁、解除死锁之后恢复、对代码进行优化等;若找不到死锁的话,后面的步骤就无从谈起了。下面就来看一下是如何用命令行的方式找到死锁的。命令:jstack这个命令叫作 jstack,它能看到我们 Java 线程的一些相关信息。如果是比较明显的死锁关系,那么这个工具就可以直接检测出来;如果原创 2021-02-17 13:12:08 · 275 阅读 · 1 评论 -
68-发生死锁必须满足哪 4 个条件?
发生死锁的 4 个必要条件要想发生死锁有 4 个缺一不可的必要条件,我们一个个来看:第 1 个叫互斥条件,它的意思是每个资源每次只能被一个线程(或进程,下同)使用,为什么资源不能同时被多个线程或进程使用呢?这是因为如果每个人都可以拿到想要的资源,那就不需要等待,所以是不可能发生死锁的。第 2 个是请求与保持条件,它是指当一个线程因请求资源而阻塞时,则需对已获得的资源保持不放。如果在请求资源时阻塞了,并且会自动释放手中资源(例如锁)的话,那别人自然就能拿到我刚才释放的资源,也就不会形成死锁。原创 2021-02-16 16:10:58 · 122 阅读 · 1 评论 -
67-如何写一个必然死锁的例子?
死锁是什么?有什么危害?什么是死锁发生在并发中首先你要知道,死锁一定发生在并发场景中。我们为了保证线程安全,有时会给程序使用各种能保证并发安全的工具,尤其是锁,但是如果在使用过程中处理不得当,就有可能会导致发生死锁的情况。互不相让死锁是一种状态,当两个(或多个)线程(或进程)相互持有对方所需要的资源,却又都不主动释放自己手中所持有的资源,导致大家都获取不到自己想要的资源,所有相关的线程(或进程)都无法继续往下执行,在未改变这种状态之前都不能向前推进,我们就把这种状态称为死锁状态,认为它们发生了死锁原创 2021-02-15 10:41:35 · 209 阅读 · 0 评论 -
66-CAS 有什么缺点?
CAS 是有很多优点的,比如可以避免加互斥锁,可以提高程序的运行效率,但是同样 CAS 也有非常明显的缺点。所以我们在使用 CAS 的时候应该同时考虑到它的优缺点,合理地进行技术选型。下面我们就来看一下 CAS 有哪几个主要的缺点。ABA 问题首先,CAS 最大的缺点就是 ABA 问题。决定 CAS 是否进行 swap 的判断标准是“当前的值和预期的值是否一致”,如果一致,就认为在此期间这个数值没有发生过变动,这在大多数情况下是没有问题的。但是在有的业务场景下,我们想确切知道从上一次看到这个值以来原创 2021-02-12 19:44:42 · 1987 阅读 · 4 评论 -
65- CAS 和乐观锁的关系,什么时候会用到 CAS?
并发容器Doug Lea 大神在 JUC 包中大量使用了 CAS 技术,该技术既能保证安全性,又不需要使用互斥锁,能大大提升工具类的性能。下面我将通过两个例子来展示 CAS 在并发容器中的使用情况。案例一:ConcurrentHashMap先来看看并发容器 ConcurrentHashMap 的例子,我们截取部分 putVal 方法的代码,如下所示:final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null |原创 2021-02-12 00:01:09 · 200 阅读 · 1 评论 -
58-Java 中的原子操作有哪些注意事项?
什么是原子性和原子操作在编程中,具备原子性的操作被称为原子操作。原子操作是指一系列的操作,要么全部发生,要么全部不发生,不会出现执行一半就终止的情况。比如转账行为就是一个原子操作,该过程包含扣除余额、银行系统生成转账记录、对方余额增加等一系列操作。虽然整个过程包含多个操作,但由于这一系列操作被合并成一个原子操作,所以它们要么全部执行成功,要么全部不执行,不会出现执行一半的情况。比如我的余额已经扣除,但是对方的余额却不增加,这种情况是不会出现的,所以说转账行为是具备原子性的。而具有原子性的原子操作,天然具原创 2021-02-04 15:39:26 · 163 阅读 · 7 评论 -
57-什么是指令重排序?为什么要重排序?
什么是重排序假设我们写了一个 Java 程序,包含一系列的语句,我们会默认期望这些语句的实际运行顺序和写的代码顺序一致。但实际上,编译器、JVM 或者 CPU 都有可能出于优化等目的,对于实际指令执行的顺序进行调整,这就是重排序。重排序的好处:提高处理速度你可能感到很困惑,为什么要重排序?这样做有什么好处呢?我们来举一个具体的例子。图中左侧是 3 行 Java 代码,右侧是这 3 行代码可能被转化成的指令。可以看出 a = 100 对应的是 Load a、Set to 100、Store a,意原创 2021-02-02 18:31:02 · 345 阅读 · 3 评论 -
39-原子类是如何利用 CAS 保证线程安全的?
什么是原子类?原子类有什么作用?要想回答这个问题,首先我们需要知道什么是原子类,以及它有什么作用。在编程领域里,原子性意味着“一组操作要么全都操作成功,要么全都失败,不能只操作成功其中的一部分”。而 java.util.concurrent.atomic 下的类,就是具有原子性的类,可以原子性地执行添加、递增、递减等操作。比如之前多线程下的线程不安全的 i++ 问题,到了原子类这里,就可以用功能相同且线程安全的 getAndIncrement 方法来优雅地解决。原子类的作用和锁有类似之处,是为了保证并原创 2021-01-07 22:48:49 · 161 阅读 · 0 评论