java 中的 CountDownLatch 有什么意义?
What's the point of CountDownLatch in java?
CountDownLatch
in java 是高级同步实用程序,用于防止特定线程开始处理,直到所有线程都准备就绪。
但是,Semaphore
完全可以做到同样的事情。那么,CountDownLatch
的优点是什么?
还有一个问题:如果CountDownLatch
确实有一些优点,为什么它被设计成只使用一次?我认为添加一个设置方法来重置很容易计数。
具有 n 个块的 信号量 当 达到 0 时。
一个CountDownLatch个块直到达到0。然后全部在大约同一时间继续。
So a semaphore is like a gate keeper at the disco, and a count down latch like a start shot at game courses.
在语义上,它们是不同的;这很重要,因为它使您的代码更易于阅读。当我看到 Semaphore 时,我立即开始思考 "a limited amount of a shared resource." 当我看到 CountDownLatch 时,我立即开始思考 "a bunch of threads waiting for the 'go!' signal." 如果你在实际需要后者的代码中给我前者,那会令人困惑。
从这个意义上讲,信号量用作 CountDownLatch 有点像 garden-path sentence;虽然在技术上是正确的,但它会使人们误入歧途并使他们感到困惑。
就更实用的用途而言,如果您只需要 CountDownLatch,那就更简单了。越简单越好!
至于重复使用 CountDownLatch,这会使它的使用变得复杂。例如,假设您正尝试将线程 A、B 和 C 排队等待某些工作。你让他们等待闩锁,然后你释放它。然后你重置它,大概是为了让线程 D、E 和 F 排队等待其他工作。但是,如果(由于竞争条件)线程 B 尚未真正从第一个闩锁中释放,会发生什么情况?如果它还没有接到 await()
电话怎么办?你是否关闭它的门,并告诉它与 D、E 和 F 一起等待第二次打开?如果第二次打开取决于 B 应该做的工作,那甚至可能导致死锁!
当我第一次阅读 CountDownLatch 时,我也有过关于重置的相同问题。但在实践中,我什至很少想重新设置一个; "wait then go" 的每个单元(A-B-C,然后是 D-E-F)自然地适合创建自己的 CountDownLatch 以配合它,事情保持美好和简单。
Semaphore can totally do the same thing. So, what's the point of CountDownLatch?
Semaphore
维护一组许可证。如果有必要,每个 acquire()
都会阻塞,直到获得许可,然后再拿走它。每个 release()
添加一个许可,可能会释放一个阻塞的获取者。
但是,没有使用实际的许可对象; 信号量只记录可用数量并相应地采取行动。
Semaphore
阻塞了进入临界区的入口,CountDownLatch
阻塞了主线程的执行,除非其他线程完成任务.
查看此 SE 问题了解更多详情:
CountDownLatch vs. Semaphore
If CountDownLatch do have some points, Why It was designed to used only once?
如果要重复使用,就用CyclicBarrier
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
CountDownLatch 的 Javadocs 引用:
CountDownLatch 是一种一次性现象 -- 无法重置计数。 如果您需要重置计数的版本,请考虑使用 CyclicBarrier。
CountDownLatch
in java 是高级同步实用程序,用于防止特定线程开始处理,直到所有线程都准备就绪。
但是,Semaphore
完全可以做到同样的事情。那么,CountDownLatch
的优点是什么?
还有一个问题:如果CountDownLatch
确实有一些优点,为什么它被设计成只使用一次?我认为添加一个设置方法来重置很容易计数。
具有 n 个块的 信号量 当 达到 0 时。
一个CountDownLatch个块直到达到0。然后全部在大约同一时间继续。
So a semaphore is like a gate keeper at the disco, and a count down latch like a start shot at game courses.
在语义上,它们是不同的;这很重要,因为它使您的代码更易于阅读。当我看到 Semaphore 时,我立即开始思考 "a limited amount of a shared resource." 当我看到 CountDownLatch 时,我立即开始思考 "a bunch of threads waiting for the 'go!' signal." 如果你在实际需要后者的代码中给我前者,那会令人困惑。
从这个意义上讲,信号量用作 CountDownLatch 有点像 garden-path sentence;虽然在技术上是正确的,但它会使人们误入歧途并使他们感到困惑。
就更实用的用途而言,如果您只需要 CountDownLatch,那就更简单了。越简单越好!
至于重复使用 CountDownLatch,这会使它的使用变得复杂。例如,假设您正尝试将线程 A、B 和 C 排队等待某些工作。你让他们等待闩锁,然后你释放它。然后你重置它,大概是为了让线程 D、E 和 F 排队等待其他工作。但是,如果(由于竞争条件)线程 B 尚未真正从第一个闩锁中释放,会发生什么情况?如果它还没有接到 await()
电话怎么办?你是否关闭它的门,并告诉它与 D、E 和 F 一起等待第二次打开?如果第二次打开取决于 B 应该做的工作,那甚至可能导致死锁!
当我第一次阅读 CountDownLatch 时,我也有过关于重置的相同问题。但在实践中,我什至很少想重新设置一个; "wait then go" 的每个单元(A-B-C,然后是 D-E-F)自然地适合创建自己的 CountDownLatch 以配合它,事情保持美好和简单。
Semaphore can totally do the same thing. So, what's the point of CountDownLatch?
Semaphore
维护一组许可证。如果有必要,每个 acquire()
都会阻塞,直到获得许可,然后再拿走它。每个 release()
添加一个许可,可能会释放一个阻塞的获取者。
但是,没有使用实际的许可对象; 信号量只记录可用数量并相应地采取行动。
Semaphore
阻塞了进入临界区的入口,CountDownLatch
阻塞了主线程的执行,除非其他线程完成任务.
查看此 SE 问题了解更多详情:
CountDownLatch vs. Semaphore
If CountDownLatch do have some points, Why It was designed to used only once?
如果要重复使用,就用CyclicBarrier
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
CountDownLatch 的 Javadocs 引用:
CountDownLatch 是一种一次性现象 -- 无法重置计数。 如果您需要重置计数的版本,请考虑使用 CyclicBarrier。