版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Megustas_JJC/article/details/84026860
整体上对三个概念进行一个说明:
CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:
- CountDownLatch是闭锁,相当于一扇门:在闭锁达到结束状态之前,这扇门一直是关闭的,并且没有任何线程能够通过,当到达结束状态时,这扇门会打开,允许所有线程通过。当闭锁到达结束状态之后,将不会再改变状态,将永远保持打开状态。
- 栅栏能够阻塞一组线程,直到某个事件发生。当线程到达栅栏位置将调用await()方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,所有线程都被释放,而栅栏将被重置以便下次使用。
- 闭锁与栅栏的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待时间,而栅栏用于等待其他线程。闭锁是一次性对象,一旦进入终止状态,就不能被重置。
计数信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。Semaphore还可以用来实现某种资源池或对容器施加边界。Semaphore管理一组虚拟的许可(permit)
具体可以参见一篇博文:Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
其中有处关于Semaphore的release()的解释感觉讲解的不太准确,参考官方api进行一个更正:
/**
* Releases a permit, returning it to the semaphore.
*
* <p>Releases a permit, increasing the number of available permits by
* one. If any threads are trying to acquire a permit, then one is
* selected and given the permit that was just released. That thread
* is (re)enabled for thread scheduling purposes.
*
* <p>There is no requirement that a thread that releases a permit must
* have acquired that permit by calling
* Correct usage of a semaphore is established by programming convention
* in the application.
*/
public void release() {
sync.releaseShared(1);
}
一个线程调用release()方法前不是必须得调用过acquire()方法,但是最后一句提到:semaphore正确的用法应该由应用程序去建立
可以将acquire()视为是消费一个许可,而release()操作是创建一个许可,Semaphore并不受限于它在创建时的初始许可数量
Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限