CountDownLatch和CyclicBarrier的真实生活示例

Sun*_*pta 27 java concurrency conceptual

我们的一位培训师在解释CountDownLatch和CyclicBarrier之间的差异时给出了一个例子.

CountDownLatch:假设一块石头可以被10个人抬起,所以你将等待所有10个人来.然后只有你可以抬起石头.

CyclicBarrier:如果你要去野餐,你需要先在一个共同的地方见面,从那里开始你的旅程.

如果有人同意这些意见,请给我一些细节.

我已经阅读了这两个类的sun API.但我还需要一些解释.

Sha*_*mar 45

在一个假想的剧院里,

如果N 个人允许观看比赛 ,如果只有一个人允许观看比赛被称为信号量,则称为Mutex.如果 有人在比赛期间离开剧院,则可以允许其他人观看比赛. 它被称为CountDownLatch如果没有人允许进入,直到每个人都离开剧院.这里每个人都有自愿离开剧院. 它被称为Cyclicbarrier,如果剧院不会开始,直到每个人进入剧院.在这里,showman无法开始演出,直到所有人进入并抓住座位.一旦比赛完成相同的障碍将适用于下一场秀



在这里,人是线程,游戏是资源.

  • 这是一个令人赞叹的学术水平的例子!非常感谢你! (2认同)

Dav*_*ess 39

关键区别在于CountDownLatch将线程分为服务员和到达者,而所有使用a的线程CyclicBarrier都执行两种角色.

  • 使用闩锁,服务员等待最后到达的线程到达,但那些到达的线程不会自行等待.
  • 有了屏障,所有线程都会到达,然后等待最后一个到达.

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

  • @SAM - 错误的,只有在锁存块上调用`await`的线程,直到倒计时到零.调用`countDown`的线程不会阻塞. (4认同)

小智 15

真实世界的例子我可以看到所有答案实际上都缺少一个真实的例子.就如何在软件领域中使用这些类一样

  1. CountDownLatch 多线程下载管理器.下载管理器将启动多个线程同时下载文件的每个部分.(前提是服务器支持多个线程下载).这里每个线程将调用实例化锁存器的倒计时方法.在所有线程完成执行之后,与倒计时锁存器相关联的线程将把不同部分中找到的部分集成到一个文件中

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

如果有什么不妥,请纠正我.


Yve*_*tin 5

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

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

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

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