![](/img/trans.png)
[英]what's the difference between CyclicBarrier/CountDownLatch and join in Java?
[英]Why does Java have both CountDownLatch and CyclicBarrier?
我正在阅读多线程并遇到这些多线程概念,我读到了差异,当我们应该使用这些时,但我无法理解为什么Java有两个类做同样的工作?
CyclicBarrier
可以完成CountDownLatch
所做的一切,那么为什么Java标准库中的CountDownLatch
呢?
CyclicBarrier可以完成CountDownLatch所做的一切,那么为什么Java标准库中的isCountDownLatch呢?
并不是的。
两者之间最大的区别不是一个是可重用的而另一个不是。 不同之处在于状态发生变化。 对于latch - 当某人 (那是键!)调用countDown()方法时,而对于Barrier - 当一个线程 (那是键)到达await()方法时。
所以基本上,我们在这里有不同的度量单位 - 一个用于调用countDown()的次数,另一个用于等待线程的数量。
考虑两个例子:
// thread 1
for (int i = 0; i < 10; i++) {
latch.countDown() //perfectly fine
}
//thread 2
for (int i = 0; i < 10; i++) {
barrier.await() //oops
}
考虑到有效两者都是不同事物的计数器,它们的特征在某种程度上相交。
一个简短但没有过于详细的答案......首先链接到各自的javadocs:
tl; dr:主要区别在于,与CyclicBarrier
不同,一旦CountDownLatch
完成并且结束,它就不能被重用。 javadoc明确提到它:
这是一次性现象 - 计数无法重置。 如果您需要重置计数的版本,请考虑使用CyclicBarrier。
事实上,我们发现CyclicBarrier
有一个名为.reset()
的方法,它实现了它的意思。 不仅如此, 还有一个CyclicBarrier
的构造函数的版本,它将每次屏障“跳闸”时运行的Runnable
关联起来(这就是javadoc所说的;不要问我)。
因此,这些确实是不同的,因为一个是可重用的( CyclicBarrier
),而另一个不是( CountDownLatch
)。
你在谈论一个常见的问题。 有时确实JDK提供的某些类在功能上是重叠的。
另一个例子是CountDownLatch
和Semaphore
。 基本上你可以在没有太大功能差异的情况下替换另一个。 这篇文章: CountDownLatch vs. Semaphore可能有助于你的困惑。
我想你可以选择一个可以让你的代码更容易理解的代码。 在您的情况下,如果您使用CyclicBarrier
,它将永远不会自行重置,因此您最好使用CountDownLatch
,这使代码更容易理解。
以Semaphore
的构造函数为例:JDK提供了两个构造函数
1 public Semaphore(int permits) {
2 sync = new NonfairSync(permits);
3 }
和
1 public Semaphore(int permits, boolean fair) {
2 sync = fair ? new FairSync(permits) : new NonfairSync(permits);
3 }
我们可以使用Semaphore(3,false)
来替换Semaphore(3)
而没有任何区别,它们都构造了一个非公平版本的信号量。 但是为什么JDK仍然提供两个版本的构造函数? 因为从中选择正确的代码可以使代码更易于阅读和理解。
除了标准差异之外,两者的原因是它们提供不同的功能而不是真正完全重叠。 例如-
所以,它真的取决于你使用哪一个。
这是我的2美分:
CountDownLatch
允许线程A等待线程B,但不要求线程B等待线程A.这可以用于需要一个线程不间断工作的场景,而另一个线程必须在该线程上的某些点上同步。
另一方面, CyclicBarrier
要求2个线程相互同步,这是两者之间的核心差异。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.