1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-20 22:17:09 +08:00

Update AQS原理以及AQS同步组件总结.md

This commit is contained in:
guide 2021-01-18 19:47:20 +08:00
parent c7808b5602
commit 9f639bf093

View File

@ -316,16 +316,16 @@ Semaphore 有两种模式,公平模式和非公平模式。
**这两个构造方法,都必须提供许可的数量,第二个构造方法可以指定是公平模式还是非公平模式,默认非公平模式。** **这两个构造方法,都必须提供许可的数量,第二个构造方法可以指定是公平模式还是非公平模式,默认非公平模式。**
[issue645补充内容](https://github.com/Snailclimb/JavaGuide/issues/645) Semaphore与CountDownLatch一样也是共享锁的一种实现。它默认构造AQS的state为permits。当执行任务的线程数量超出permits,那么多余的线程将会被放入阻塞队列Park,并自旋判断state是否大于0。只有当state大于0的时候阻塞的线程才能继续执行,此时先前执行任务的线程继续执行release方法release方法使得state的变量会加1那么自旋的线程便会判断成功。 [issue645 补充内容](https://github.com/Snailclimb/JavaGuide/issues/645) Semaphore CountDownLatch 一样,也是共享锁的一种实现。它默认构造 AQS state permits。当执行任务的线程数量超出 permits,那么多余的线程将会被放入阻塞队列 Park,并自旋判断 state 是否大于 0。只有当 state 大于 0 的时候,阻塞的线程才能继续执行,此时先前执行任务的线程继续执行 release 方法release 方法使得 state 的变量会加 1那么自旋的线程便会判断成功。
如此每次只有最多不超过permits数量的线程能自旋成功便限制了执行任务线程的数量。 如此,每次只有最多不超过 permits 数量的线程能自旋成功,便限制了执行任务线程的数量。
由于篇幅问题,如果对 Semaphore 源码感兴趣的朋友可以看下这篇文章https://juejin.im/post/5ae755366fb9a07ab508adc6 由于篇幅问题,如果对 Semaphore 源码感兴趣的朋友可以看下这篇文章https://juejin.im/post/5ae755366fb9a07ab508adc6
### 4 CountDownLatch (倒计时器) ### 4 CountDownLatch (倒计时器)
CountDownLatch允许 count 个线程阻塞在一个地方,直至所有线程的任务都执行完毕。在 Java 并发中countdownlatch 的概念是一个常见的面试题,所以一定要确保你很好的理解了它。 `CountDownLatch` 允许 `count` 个线程阻塞在一个地方,直至所有线程的任务都执行完毕。
CountDownLatch是共享锁的一种实现,它默认构造 AQS 的 state 值为 count。当线程使用countDown方法时,其实使用了`tryReleaseShared`方法以CAS的操作来减少state,直至state为0就代表所有的线程都调用了countDown方法。当调用await方法的时候如果state不为0就代表仍然有线程没有调用countDown方法那么就把已经调用过countDown的线程都放入阻塞队列Park,并自旋CAS判断state == 0直至最后一个线程调用了countDown使得state == 0于是阻塞的线程便判断成功全部往下执行。 `CountDownLatch` 是共享锁的一种实现,它默认构造 AQS 的 `state` 值为 `count`。当线程使用 `countDown()` 方法时,其实使用了`tryReleaseShared`方法以 CAS 的操作来减少 `state`,直至 `state` 为 0 。当调用 `await()` 方法的时候,如果 `state` 不为 0那就证明任务还没有执行完毕`await()` 方法就会一直阻塞,也就是说 `await()` 方法之后的语句不会被执行。然后,`CountDownLatch` 会自旋 CAS 判断 `state == 0`,如果 `state == 0` 的话,就会释放所有等待的线程,`await()` 方法之后的语句得到执行。
#### 4.1 CountDownLatch 的两种典型用法 #### 4.1 CountDownLatch 的两种典型用法
@ -393,7 +393,7 @@ for (int i = 0; i < threadCount-1; i++) {
这样就导致 `count` 的值没办法等于 0然后就会导致一直等待。 这样就导致 `count` 的值没办法等于 0然后就会导致一直等待。
如果对CountDownLatch源码感兴趣的朋友可以查看 [【JUC】JDK1.8源码分析之CountDownLatch](https://www.cnblogs.com/leesf456/p/5406191.html) 如果对 CountDownLatch 源码感兴趣的朋友,可以查看: [【JUC】JDK1.8 源码分析之 CountDownLatch](https://www.cnblogs.com/leesf456/p/5406191.html)
#### 4.3 CountDownLatch 的不足 #### 4.3 CountDownLatch 的不足
@ -413,7 +413,7 @@ CountDownLatch 类中主要的方法?
CyclicBarrier 和 CountDownLatch 非常类似,它也可以实现线程间的技术等待,但是它的功能比 CountDownLatch 更加复杂和强大。主要应用场景和 CountDownLatch 类似。 CyclicBarrier 和 CountDownLatch 非常类似,它也可以实现线程间的技术等待,但是它的功能比 CountDownLatch 更加复杂和强大。主要应用场景和 CountDownLatch 类似。
> CountDownLatch的实现是基于AQS的而CycliBarrier是基于 ReentrantLock(ReentrantLock也属于AQS同步器)和 Condition 的. > CountDownLatch 的实现是基于 AQS 的,而 CycliBarrier 是基于 ReentrantLock(ReentrantLock 也属于 AQS 同步器)和 Condition 的.
CyclicBarrier 的字面意思是可循环使用Cyclic的屏障Barrier。它要做的事情是让一组线程到达一个屏障也可以叫同步点时被阻塞直到最后一个线程到达屏障时屏障才会开门所有被屏障拦截的线程才会继续干活。CyclicBarrier 默认的构造方法是 `CyclicBarrier(int parties)`,其参数表示屏障拦截的线程数量,每个线程调用`await`方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。 CyclicBarrier 的字面意思是可循环使用Cyclic的屏障Barrier。它要做的事情是让一组线程到达一个屏障也可以叫同步点时被阻塞直到最后一个线程到达屏障时屏障才会开门所有被屏障拦截的线程才会继续干活。CyclicBarrier 默认的构造方法是 `CyclicBarrier(int parties)`,其参数表示屏障拦截的线程数量,每个线程调用`await`方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。
@ -726,4 +726,3 @@ ReentrantLock 和 synchronized 的区别在上面已经讲过了这里就不多
**Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。 **Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源公众号后台回复关键字 **“1”** 即可免费无套路获取。
![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png) ![我的公众号](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png)