我正在阅读多线程,并且遇到了多线程概念,我读到了差异,当我们应该使用它们时,但是我无法理解为什么Java有两个同样工作的类?
CyclicBarrier
可以执行CountDownLatch
所做的所有操作,那么为什么Java标准库中有CountDownLatch
?
答案 0 :(得分:3)
简短而不是过于详细的答案......首先是指向各自javadocs的链接:
tl; dr:主要的区别在于,与CyclicBarrier
不同,一旦CountDownLatch
完成并且结束,它就无法重复使用。 javadoc明确提到它:
这是一次性现象 - 计数无法重置。如果您需要一个重置计数的版本,请考虑使用CyclicBarrier。
事实上,我们发现CyclicBarrier
有一个名为.reset()
的方法,它实现了它的意思。不仅如此,而且there is a version of the constructor of a CyclicBarrier
每当障碍物被“绊倒”时,Runnable
与CyclicBarrier
相关联。 (这就是javadoc所说的;不要问我)。
所以,这些确实是不同的,因为一个是可重用的(CountDownLatch
),而另一个不是(itemsArr
)。
答案 1 :(得分:3)
CyclicBarrier可以完成CountDownLatch所做的一切,为什么呢 Java标准库中的isCountDownLatch?
不是真的。
两者之间最大的区别不在于一个是可重用的而另一个不是。不同之处在于状态发生变化。对于latch - 当某人(那是键!)调用 countDown()方法时,对于Barrier - 当线程时(这是关键的)到达 await()方法。
所以基本上,我们在这里有不同的度量单位 - 一个是根据对 countDown()的调用次数进行操作,而另一个是等待线程 p>
考虑两个例子:
// 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
}
考虑到两者都是不同事物的计数器,它们的特征在某种程度上相交。
答案 2 :(得分:0)
您正在谈论一个常见问题。有时确实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仍然提供两个版本的构造函数?因为从中选择正确的代码可以使代码更易于阅读和理解。
答案 3 :(得分:0)
除了标准差异之外,两者兼顾的原因是它们提供不同的功能而不是真正完全重叠。例如 -
所以,这实际上取决于你使用哪一个。
答案 4 :(得分:0)
这是我的2美分:
CountDownLatch
允许线程A等待线程B,但不要求线程B等待线程A。这可用于需要一个线程不间断工作而另一个线程必须同步的情况下。该线程上的一些要点。
另一方面,CyclicBarrier
要求2个线程彼此同步,这是两者之间的核心区别。