Java并发编程实战:闭锁CountDownLatch,栅栏CyclicBarrier与信号量Semaphore

整体上对三个概念进行一个说明:

CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:

  • CountDownLatch是闭锁,相当于一扇门:在闭锁达到结束状态之前,这扇门一直是关闭的,并且没有任何线程能够通过,当到达结束状态时,这扇门会打开,允许所有线程通过。当闭锁到达结束状态之后,将不会再改变状态,将永远保持打开状态。
  • 栅栏能够阻塞一组线程,直到某个事件发生。当线程到达栅栏位置将调用await()方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,所有线程都被释放,而栅栏将被重置以便下次使用。
  • 闭锁与栅栏的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待时间,而栅栏用于等待其他线程。闭锁是一次性对象,一旦进入终止状态,就不能被重置。

计数信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。Semaphore还可以用来实现某种资源池或对容器施加边界。Semaphore管理一组虚拟的许可(permit)

具体可以参见一篇博文:Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

其中有处关于Semaphore的release()的解释感觉讲解的不太准确,参考官方api进行一个更正:

/**
    * Releases a permit, returning it to the semaphore.
    *
    * 

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. * *

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其实和锁有点类似,它一般用于控制对某组资源的访问权限

你可能感兴趣的:(并发)