2012-04-14 31 views
15

当他解释CountDownLatch和CyclicBarrier之间的区别时,我们的一位培训师给出了一个示例。CountDownLatch和CyclicBarrier的真实生活实例

CountDownLatch:假设一块石头可以被10人抬起,所以你会等待所有10人来。那么只有你可以举起石头。

CyclicBarrier:如果你要去野餐,而且你需要先在一些常见的地方见面,那么你将从哪里开始你的旅程。

如果有人同意这些评论,请给我一些细节。

我已经阅读了这两个类的sun API。但我需要更多的解释。

+0

请参阅此http://mkorytin.blogspot.in/2011/07/cyclicbarrier-countdownlatch-and.html和http://shazsterblog.blogspot.in/2011/12/comparison-of-countdownlatch.html ..一些非常好的理解和例子 – 2013-04-05 19:06:40

+0

另一个链接,你可能会觉得有用的是 http://adnanfaizan.blogspot.in/2013/10/countdownlatch-tutorial-class-of-java.html – 2013-10-05 17:44:43

+0

@Sunny这是现在老问题,但这对我来说是新的。你能否回答2个问题(1)。您的循环屏障示例(野餐)在此处是否正确?问题2)。在这个循环障碍的例子中,如果有10个人去野餐,他们需要在一些共同的地方见面,在那里所有的人都会重新开始他们的旅程。在到达俱乐部(或目的地)之前,他们可以在这段旅程中为所有线程满足多个共同点。 – 2017-06-29 15:50:50

回答

29

关键区别在于CountDownLatch将线程分隔为等待者和到达者,而所有使用CyclicBarrier的线程都执行这两个角色。

  • 通过锁存器,服务员等待最后到达的线程到达,但那些到达的线程不会自行等待。
  • 有障碍,所有的线程到达,然后等待最后到达。

你的闩锁示例意味着所有十个人必须等待将石头一起抬起。不是这种情况。一个更好的现实世界的例子是一个考试提醒者,耐心地等待每个学生交出他们的考试。学生一旦完成考试并且可以自由离开,就不会等待。一旦最后一名学生参加考试(或时限到期),提醒者停止等待并离开考试。

+0

“有了门闩,服务员等待最后到达的线程到达,但是到达的线程不会自己等待。”根据我的理解,情况并非如此。因为主线程总是等待所有线程倒数到0.请解释。 – 2012-04-17 06:55:00

+0

这个例子应该像一个协调员检查是否有10人可以吊起石头。我对吗?? – 2012-04-17 06:58:56

+4

@SAM - 错误的,只有在锁定块上调用await的线程,直到倒数到零。调用'countDown'的线程不会被阻塞。 – 2012-04-17 17:32:20

4

使用案例1假设您已将大型作业分成10个小型任务,每个任务都是一个线程。在考虑完成工作之前,你必须等待这10个任务的结束。

因此,主作业启动器线程将CountDownLatch初始化为所使用线程的数量,它将任务分配给线程并等待锁定将采用await方法提升为零。每个执行程序线程将在其任务结束时调用countDown。最后,当所有线程都完成时,主线程将被唤醒,以便它认为所有工作都已完成。该场景使用CountDownLatch javadoc中描述的doneSignal锁存器。

使用案例2假设您已将大型作业拆分为分布在n个线程上的n * m个任务。 m对应于一个矩阵行,并且您有一个总数来计算每行。在这种情况下,必须在每个任务结束后同步线程,以便该行的总和为compute。在这种情况下,使用线程数n初始化的CyclicBarrier用于等待每个行计算的结束(实际上是m次)。

为了比较两者,CountDownLatch应该只使用1次,并且CyclicBarrier可以多次使用,因为该算法需要一组线程的同步点。

4

A CyclicBarrier是可重复使用的,所以它更像是一个赛车巡回赛,在巡回赛的下一站之前,每个人都在一个航点上相遇。

+0

讨论'CountDownLatch'示例[这里](http://stackoverflow.com/a/3588523/230513)。 – trashgod 2012-04-14 18:55:49

0

CountDownLatch: 如果我们希望我们所有的线程做

东西+倒计时

使其他等待(用于计数到达零)线程能继续,我们可以使用倒计时闩锁。所有以前的线程都可以在这种情况下继续进行倒计时,但不能保证在latch.countdown()等待其他线程到达latch.countdown()后,行会被处理() 但它有一个保证其他等待线程只会在latch.await()达到零后才会启动。

的CyclicBarrier: 如果我们希望所有的线程

做点什么+等待在公共点+做点什么

(每个等待通话将减少等待时间的线程进行在进一步)

CyclicBarrier功能可以通过调用latch.countdown(),然后由所有latch.await()由所有CountDownLatch实现一次线程。

但你不能重置/重用countdownlatch。

我使用CyclicBarrier的最佳示例是初始化多个缓存(由多个线程加热),然后开始进一步处理,并且我想在同步中再次重新初始化其他缓存。

15

在假设剧院,

它被称为互斥,如果只有一个人让观看该剧
它被称为信号灯如果人N多让观看play.If有人离开戏剧期间可以允许其他人观看比赛。
它被称为CountDownLatch如果没有人允许进入,直到每个人腾空剧院。这里每个人都有自由离开剧院。
它被称为循环障碍如果影院不会开始,直到每个人都进入影院。这里showman不能开始表演,直到所有人进入并抓住座位。一旦完成同样的障碍将申请下一个节目

在这里,人是线程,玩是资源。

3

理论分野:

在CountDownLatch,主线程等待其他线程完成其执行。 在CyclicBarrier中,工作线程互相等待以完成其执行。

一旦计数达到零并且锁存器打开,您就无法重复使用相同的CountDownLatch实例。另一方面,可以通过重置屏障重新使用循环障碍,一旦障碍被打破。

活生生的例子: -

CountDownLatch:考虑一个IT世界场景经理划分开发团队之间的模块(A和B),他希望把它分配给QA团队进行测试,只有当两支队伍都完成了他们的任务。

这里管理器线程作为主线程工作,开发团队作为工作线程工作。经理线程等待开发团队线程完成他们的任务。

CyclicBarrier:考虑一下IT经理在开发团队(A和B)之间划分模块的情况。他请假,并要求两个团队在完成相关任务后等待对方完成任务,然后将其分配给QA团队进行测试。

这里管理器线程作为主线程工作,开发团队作为工作线程工作。开发团队线程在完成任务后等待其他开发团队线程。

5

真实世界示例 我可以看到所有的答案实际上都缺少一个真实的例子。由于在如何将这些类可以在软件领域

  1. CountDownLatch 一个多线程下载管理器中使用。 下载管理器将启动多个线程同时下载文件的每个部分(如果服务器支持多个线程下载)。这里每个线程都会调用实例化锁存器的倒数方法。在所有的线程都执行完毕,用倒计时锁将整合在不同部分中发现的部分结合在一起成一个文件

  2. 的CyclicBarrier 相同的情况above..But假设文件是​​从下载的线程P2P。再次多个线程下载件。但是,在这里,假设您希望在特定的时间间隔之后对下载的部分进行intergity检查。这里的循环障碍起着重要的作用。在每个时间间隔之后,每个线程将在屏障处等待,以便与cyclibarrier关联的线程可以执行完整性检查。这完整性检查可以多由于时间做的CyclicBarrier

如果有什么不正确,请大家指正。

0

顾名思义的循环屏障可用于循环。 例如: 我是一家公司,希望从各种招聘门户网站Feed中获取N份简历。 我有一个技能组数组,其中包含按优先级排序的技能。 对于前java,c#,python。我想找到N个恢复匹配java技能组, ,但如果我没有找到所需的号码。的简历,我再次搜索 上的下一个技能等。

我创建了一个工作人员,每个工作人员扫描简历,分配给职位的 。这两名工作人员都将从其职位Feed中的主要技能组搜索 开始。

执行搜索后,工作人员将检查N是否恢复 被找到。如果找到,工人将重置障碍,并返回 。否则它会等待另一名工人完成。 如果还没有找到N个简历,那么搜索将再次恢复 ,在技能组数组的下一个技能上。 因此,可以递归地/循环地调用搜索,而不需要 创建新的循环屏障。