4
4
5
5
- [ 1 AQS 简单介绍] ( #1-aqs-简单介绍 )
6
6
- [ 2 AQS 原理] ( #2-aqs-原理 )
7
- - [ 2.1 AQS 原理概览] ( #21-aqs-原理概览 )
8
- - [ 2.2 AQS 对资源的共享方式] ( #22-aqs-对资源的共享方式 )
9
- - [ 2.3 AQS 底层使用了模板方法模式] ( #23-aqs-底层使用了模板方法模式 )
7
+ - [ 2.1 AQS 原理概览] ( #21-aqs-原理概览 )
8
+ - [ 2.2 AQS 对资源的共享方式] ( #22-aqs-对资源的共享方式 )
9
+ - [ 2.3 AQS 底层使用了模板方法模式] ( #23-aqs-底层使用了模板方法模式 )
10
10
- [ 3 Semaphore(信号量)-允许多个线程同时访问] ( #3-semaphore信号量-允许多个线程同时访问 )
11
11
- [ 4 CountDownLatch (倒计时器)] ( #4-countdownlatch-倒计时器 )
12
- - [ 4.1 CountDownLatch 的三种典型用法] ( #41-countdownlatch-的三种典型用法 )
13
- - [ 4.2 CountDownLatch 的使用示例] ( #42-countdownlatch-的使用示例 )
14
- - [ 4.3 CountDownLatch 的不足] ( #43-countdownlatch-的不足 )
15
- - [ 4.4 CountDownLatch 常见面试题] ( #44-countdownlatch-相常见面试题 )
12
+ - [ 4.1 CountDownLatch 的三种典型用法] ( #41-countdownlatch-的三种典型用法 )
13
+ - [ 4.2 CountDownLatch 的使用示例] ( #42-countdownlatch-的使用示例 )
14
+ - [ 4.3 CountDownLatch 的不足] ( #43-countdownlatch-的不足 )
15
+ - [ 4.4 CountDownLatch 常见面试题] ( #44-countdownlatch-相常见面试题 )
16
16
- [ 5 CyclicBarrier(循环栅栏)] ( #5-cyclicbarrier循环栅栏 )
17
- - [ 5.1 CyclicBarrier 的应用场景] ( #51-cyclicbarrier-的应用场景 )
18
- - [ 5.2 CyclicBarrier 的使用示例] ( #52-cyclicbarrier-的使用示例 )
19
- - [ 5.3 ` CyclicBarrier ` 源码分析] ( #53-cyclicbarrier源码分析 )
20
- - [ 5.4 CyclicBarrier 和 CountDownLatch 的区别] ( #54-cyclicbarrier-和-countdownlatch-的区别 )
17
+ - [ 5.1 CyclicBarrier 的应用场景] ( #51-cyclicbarrier-的应用场景 )
18
+ - [ 5.2 CyclicBarrier 的使用示例] ( #52-cyclicbarrier-的使用示例 )
19
+ - [ 5.3 ` CyclicBarrier ` 源码分析] ( #53-cyclicbarrier源码分析 )
20
+ - [ 5.4 CyclicBarrier 和 CountDownLatch 的区别] ( #54-cyclicbarrier-和-countdownlatch-的区别 )
21
21
- [ 6 ReentrantLock 和 ReentrantReadWriteLock] ( #6-reentrantlock-和-reentrantreadwritelock )
22
22
- [ 参考] ( #参考 )
23
23
- [ 公众号] ( #公众号 )
@@ -238,7 +238,7 @@ tryReleaseShared(int)//共享方式。尝试释放资源,成功则返回true
238
238
239
239
### 3 Semaphore(信号量)-允许多个线程同时访问
240
240
241
- ** synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。**
241
+ ** synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。**
242
242
243
243
示例代码如下:
244
244
@@ -316,16 +316,16 @@ Semaphore 有两种模式,公平模式和非公平模式。
316
316
317
317
** 这两个构造方法,都必须提供许可的数量,第二个构造方法可以指定是公平模式还是非公平模式,默认非公平模式。**
318
318
319
- [ issue645补充内容 ] ( https://github.com/Snailclimb/JavaGuide/issues/645 ) :Semaphore与CountDownLatch一样 ,也是共享锁的一种实现。它默认构造AQS的state为permits。当执行任务的线程数量超出permits,那么多余的线程将会被放入阻塞队列Park,并自旋判断state是否大于0。只有当state大于0的时候 ,阻塞的线程才能继续执行,此时先前执行任务的线程继续执行release方法,release方法使得state的变量会加1 ,那么自旋的线程便会判断成功。
320
- 如此,每次只有最多不超过permits数量的线程能自旋成功 ,便限制了执行任务线程的数量。
319
+ [ issue645 补充内容 ] ( https://github.com/Snailclimb/JavaGuide/issues/645 ) :Semaphore 与 CountDownLatch 一样 ,也是共享锁的一种实现。它默认构造 AQS 的 state 为 permits。当执行任务的线程数量超出 permits,那么多余的线程将会被放入阻塞队列 Park,并自旋判断 state 是否大于 0。只有当 state 大于 0 的时候 ,阻塞的线程才能继续执行,此时先前执行任务的线程继续执行 release 方法,release 方法使得 state 的变量会加 1 ,那么自旋的线程便会判断成功。
320
+ 如此,每次只有最多不超过 permits 数量的线程能自旋成功 ,便限制了执行任务线程的数量。
321
321
322
322
由于篇幅问题,如果对 Semaphore 源码感兴趣的朋友可以看下这篇文章:https://juejin.im/post/5ae755366fb9a07ab508adc6
323
323
324
324
### 4 CountDownLatch (倒计时器)
325
325
326
- CountDownLatch允许 count 个线程阻塞在一个地方,直至所有线程的任务都执行完毕。在 Java 并发中,countdownlatch 的概念是一个常见的面试题,所以一定要确保你很好的理解了它 。
326
+ ` CountDownLatch ` 允许 ` count ` 个线程阻塞在一个地方,直至所有线程的任务都执行完毕。
327
327
328
- CountDownLatch是共享锁的一种实现 ,它默认构造 AQS 的 state 值为 count。当线程使用countDown方法时 ,其实使用了` tryReleaseShared ` 方法以CAS的操作来减少state,直至state为0就代表所有的线程都调用了countDown方法。当调用await方法的时候,如果state不为0,就代表仍然有线程没有调用countDown方法,那么就把已经调用过countDown的线程都放入阻塞队列Park,并自旋CAS判断state == 0,直至最后一个线程调用了countDown,使得state == 0,于是阻塞的线程便判断成功,全部往下执行 。
328
+ ` CountDownLatch ` 是共享锁的一种实现 ,它默认构造 AQS 的 ` state ` 值为 ` count ` 。当线程使用 ` countDown() ` 方法时 ,其实使用了` tryReleaseShared ` 方法以 CAS 的操作来减少 ` state ` ,直至 ` state ` 为 0 。当调用 ` await() ` 方法的时候,如果 ` state ` 不为 0,那就证明任务还没有执行完毕, ` await() ` 方法就会一直阻塞,也就是说 ` await() ` 方法之后的语句不会被执行。然后, ` CountDownLatch ` 会自旋 CAS 判断 ` state == 0` ,如果 ` state == 0` 的话,就会释放所有等待的线程, ` await() ` 方法之后的语句得到执行 。
329
329
330
330
#### 4.1 CountDownLatch 的两种典型用法
331
331
@@ -383,17 +383,17 @@ public class CountDownLatchExample1 {
383
383
384
384
其他 N 个线程必须引用闭锁对象,因为他们需要通知 ` CountDownLatch ` 对象,他们已经完成了各自的任务。这种通知机制是通过 ` CountDownLatch.countDown() ` 方法来完成的;每调用一次这个方法,在构造函数中初始化的 count 值就减 1。所以当 N 个线程都调 用了这个方法,count 的值等于 0,然后主线程就能通过 ` await() ` 方法,恢复执行自己的任务。
385
385
386
- 再插一嘴:` CountDownLatch ` 的 ` await() ` 方法使用不当很容易产生死锁,比如我们上面代码中的 for 循环改为:
386
+ 再插一嘴:` CountDownLatch ` 的 ` await() ` 方法使用不当很容易产生死锁,比如我们上面代码中的 for 循环改为:
387
387
388
388
``` java
389
389
for (int i = 0 ; i < threadCount- 1 ; i++ ) {
390
390
.......
391
391
}
392
392
```
393
393
394
- 这样就导致 ` count ` 的值没办法等于 0,然后就会导致一直等待。
394
+ 这样就导致 ` count ` 的值没办法等于 0,然后就会导致一直等待。
395
395
396
- 如果对CountDownLatch源码感兴趣的朋友 ,可以查看: [ 【JUC】JDK1.8源码分析之CountDownLatch (五)] ( https://www.cnblogs.com/leesf456/p/5406191.html )
396
+ 如果对 CountDownLatch 源码感兴趣的朋友 ,可以查看: [ 【JUC】JDK1.8 源码分析之 CountDownLatch (五)] ( https://www.cnblogs.com/leesf456/p/5406191.html )
397
397
398
398
#### 4.3 CountDownLatch 的不足
399
399
@@ -413,7 +413,7 @@ CountDownLatch 类中主要的方法?
413
413
414
414
CyclicBarrier 和 CountDownLatch 非常类似,它也可以实现线程间的技术等待,但是它的功能比 CountDownLatch 更加复杂和强大。主要应用场景和 CountDownLatch 类似。
415
415
416
- > CountDownLatch的实现是基于AQS的,而CycliBarrier是基于 ReentrantLock(ReentrantLock也属于AQS同步器 )和 Condition 的.
416
+ > CountDownLatch 的实现是基于 AQS 的,而 CycliBarrier 是基于 ReentrantLock(ReentrantLock 也属于 AQS 同步器 )和 Condition 的.
417
417
418
418
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier 默认的构造方法是 ` CyclicBarrier(int parties) ` ,其参数表示屏障拦截的线程数量,每个线程调用` await ` 方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。
419
419
@@ -726,4 +726,3 @@ ReentrantLock 和 synchronized 的区别在上面已经讲过了这里就不多
726
726
** Java 工程师必备学习资源:** 一些 Java 工程师常用学习资源公众号后台回复关键字 ** “1”** 即可免费无套路获取。
727
727
728
728
![ 我的公众号] ( https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/167598cd2e17b8ec.png )
729
-
0 commit comments