Java中的CountDownLatch有什么意义?

时间:2016-09-02 06:56:54

标签: java multithreading concurrency semaphore countdownlatch

java中的

CountDownLatch是一个高级同步实用程序,用于防止特定线程在所有线程准备就绪之前开始处理。

但是,Semaphore完全可以做同样的事情。那么, CountDownLatch的优点是什么?

还有一个问题:如果CountDownLatch确实有一些优点,为什么它只设计为使用一次?我认为添加set方法来重置计数很容易。

3 个答案:

答案 0 :(得分:5)

从语义上讲,它们是不同的;这很重要,因为它使您的代码更容易阅读。当我看到一个信号量时,我立即开始思考“有限数量的共享资源”。当我看到一个CountDownLatch时,我立即开始思考“一堆线程等着'去!'信号。”如果你在代码中给我前者实际上需要后者,那就太麻烦了。

从这个意义上讲,用作CountDownLatch的信号量有点像garden-path sentence;虽然技术上是正确的,但它会让人误入歧途并使他们感到困惑。

就更实用的用法而言,只要你需要,CountDownLatch就更简单了。越简单越好!

至于重用CountDownLatch,会使其使用复杂化。例如,假设您正在尝试将线程A,B和C排队等待某些工作。你让他们等待闩锁,然后你释放它。然后你重置它,大概是为了其他一些工作排​​队线程D,E和F.但是如果(由于竞争条件),线程B实际上还没有从第一个锁存器释放,会发生什么呢?如果它还没有接到await()电话怎么办?你是否关闭了门,并告诉它等待D,E和F进行第二次打开?如果第二次打开取决于B应该做的工作,那甚至可能导致死锁!

当我第一次阅读有关CountDownLatch的内容时,我遇到了与重置相同的问题。但实际上,我很少想重置一个; “等待然后去”(A-B-C,然后是D-E-F)的每个单元自然有助于创建自己的CountDownLatch以与它一起使用,并且事情保持美观和简单。

答案 1 :(得分:4)

信号量,当 0到达时,n块

到达 0的n个块 CountDownLatch 。然后所有人都在大约同一时间继续。

  

因此,信号量就像是迪斯科舞厅的守门员,倒计时闩锁就像游戏课程的开始一样。

答案 2 :(得分:1)

  

信号量完全可以做同样的事情。那么,CountDownLatch的重点是什么?

Semaphore维持一组许可。如果需要,每个acquire()阻止,直到有许可证,然后接受。每个release()都会添加一个许可证,可能会释放阻止收购者。

但是,没有使用实际的许可对象; 信号量只保留可用数量的计数并相应地采取行动

Semaphore阻止进入关键部分的条目,CountDownLatch阻止主线程的执行,除非其他线程完成其任务

有关详细信息,请查看此SE问题:

CountDownLatch vs. Semaphore

  

如果CountDownLatch确实有一些点,为什么它只被设计为使用一次?

如果要重复使用,请使用CyclicBarrier

  

一种同步辅助工具,允许一组线程全部等待彼此到达公共障碍点。 CyclicBarriers在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。屏障称为循环,因为它可以在等待线程释放后重新使用。

CountDownLatch的Javadocs引用:

CountDownLatch是一次性现象 - 计数无法重置。 如果您需要重置计数的版本,请考虑使用CyclicBarrier。