CountDownLatch,CyclicBarrier,Semaphore

Posted 少年啦飞驰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CountDownLatch,CyclicBarrier,Semaphore相关的知识,希望对你有一定的参考价值。

CountDownLatch是倒数,doneSignal = new CountDownLatch(LATCH_SIZE);赋初值后,在主线程中等待doneSignal.await();其它线程中,每完成一个就减一doneSignal.countDown();减到0时主线程继续。
CyclicBarrier是正数,cb = new CyclicBarrier(SIZE);主线程中开启各子线程,子线程调用cb.await()进行等待;cb计数count会加一,等于SIZE时会继续所有等待线程。
Semaphore是信号灯,Semaphore sem = new Semaphore(SEM_MAX);主线程中开启各子线程,子线程调用sem.acquire(count);每调用一次,sem计数会减相应数值,减为0时其它线程再调用acquire时会阻塞,线程结束后记得要sem.release(count);
 
CountDownLatch和Semaphore用的是共享锁,而CyclicBarrier是独占锁。
CountDownLatch只能赋值一次,而CyclicBarrier可赋值多次。

概要

前面对"独占锁"和"共享锁"有了个大致的了解;本章,我们对CountDownLatch进行学习。和ReadWriteLock.ReadLock一样,CountDownLatch的本质也是一个"共享锁"。本章的内容包括:
CountDownLatch简介
CountDownLatch数据结构
CountDownLatch源码分析(基于JDK1.7.0_40)
CountDownLatch示例

 

CountDownLatch简介

CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

 

CountDownLatch和CyclicBarrier的区别
(01) CountDownLatch的作用是允许1或N个线程等待其他线程完成执行;而CyclicBarrier则是允许N个线程相互等待。
(02) CountDownLatch的计数器无法被重置;CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier
关于CyclicBarrier的原理,后面一章再来学习。


CountDownLatch函数列表

CountDownLatch数据结构

CountDownLatch的UML类图如下:

 

 

CountDownLatch的数据结构很简单,它是通过"共享锁"实现的。它包含了sync对象,sync是Sync类型。Sync是实例类,它继承于AQS。

 

总结:CountDownLatch是通过“共享锁”实现的。在创建CountDownLatch中时,会传递一个int类型参数count,该参数是“锁计数器”的初始状态,表示该“共享锁”最多能被count给线程同时获取。当某线程调用该CountDownLatch对象的await()方法时,该线程会等待“共享锁”可用时,才能获取“共享锁”进而继续运行。而“共享锁”可用的条件,就是“锁计数器”的值为0!而“锁计数器”的初始值为count,每当一个线程调用该CountDownLatch对象的countDown()方法时,才将“锁计数器”-1;通过这种方式,必须有count个线程调用countDown()之后,“锁计数器”才为0,而前面提到的等待线程才能继续运行!

 

 

CyclicBarrier原理和示例

本章介绍JUC包中的CyclicBarrier锁。内容包括:
CyclicBarrier简介
CyclicBarrier数据结构
CyclicBarrier源码分析(基于JDK1.7.0_40)
CyclicBarrier示例

 

CyclicBarrier简介

CyclicBarrier是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

 

注意比较CountDownLatchCyclicBarrier
(01) CountDownLatch的作用是允许1或N个线程等待其他线程完成执行;而CyclicBarrier则是允许N个线程相互等待。
(02) CountDownLatch的计数器无法被重置;CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier。


CyclicBarrier函数列表

CyclicBarrier数据结构

CyclicBarrier的UML类图如下:

CyclicBarrier是包含了"ReentrantLock对象lock"和"Condition对象trip",它是通过独占锁实现的。下面通过源码去分析到底是如何实现的。

 

Semaphore简介

Semaphore是一个计数信号量,它的本质是一个"共享锁"。

信号量维护了一个信号量许可集。线程可以通过调用acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。


Semaphore的函数列表

Semaphore数据结构

Semaphore的UML类图如下:

从图中可以看出:
(01) 和"ReentrantLock"一样,Semaphore也包含了sync对象,sync是Sync类型;而且,Sync是一个继承于AQS的抽象类。
(02) Sync包括两个子类:"公平信号量"FairSync 和 "非公平信号量"NonfairSync。sync是"FairSync的实例",或者"NonfairSync的实例";默认情况下,sync是NonfairSync(即,默认是非公平信号量)。

以上是关于CountDownLatch,CyclicBarrier,Semaphore的主要内容,如果未能解决你的问题,请参考以下文章

AQS原理探究

AQS原理探究

Java CountDownLatch解析(下)

CountDownLatch的使用

CountDownLatch源码分析

JUC包中的CountDownLatch源码实现分析