普通的一个普通猿 2024-04-12 10:37 采纳率: 84.4%
浏览 2
已结题

介绍Java并发工具类CountDownLatch和CyclicBarrier的用途和工作原理?

介绍Java并发工具类CountDownLatch和CyclicBarrier的用途和工作原理。

  • 写回答

4条回答 默认 最新

  • JJJ69 2024-04-12 11:25
    关注

    CountDownLatch

    用途: CountDownLatch 是一种并发协作工具类,主要用于实现线程间的同步,允许一个或多个线程(称为“参与者”)等待其他线程(称为“工作者”)完成一组指定的操作后才能继续执行。常见应用场景包括:

    启动同步:例如,在一个多线程应用程序启动时,主线程等待所有子线程初始化完成后再继续执行后续操作。
    批处理任务:当一批独立的任务需要全部完成后才能进行整体处理或汇总结果时,可以使用 CountDownLatch 来确保所有任务都已完成。
    服务依赖:在分布式系统中,某个服务可能依赖于其他多个服务的启动完成,CountDownLatch 可以用来实现这些服务启动的同步等待。
    

    工作原理: CountDownLatch 内部维护了一个计数器(整数值),在构造时设置其初始值。当一个线程调用 countDown() 方法时,计数器减一。如果计数器值原本大于零,则减一后继续等待。当其他线程调用 await() 方法时,该线程将阻塞,直到计数器值为零。这意味着所有预期的 countDown() 调用都已经发生。一旦计数器减至零,所有因调用 await() 而阻塞的线程将被释放,可以继续执行。

    特点:

    一次性:CountDownLatch 是一次性使用的同步辅助类,计数器减至零后就不能再重置。
    不可逆:计数器只能递减,不能增加。一旦计数器值达到零,无法恢复到非零状态。
    无循环特性:CountDownLatch 不具备循环等待的能力,即达到屏障条件后,等待的线程不会再次进入等待状态。
    

    CyclicBarrier

    用途: CyclicBarrier 是另一种并发协作工具类,主要用于协调一组线程在某个屏障点同步汇合,当所有参与线程都到达屏障点后,它们才能继续执行后续操作。适用于以下场景:

    并行计算的阶段划分:在多阶段计算任务中,每个阶段由一组线程并行执行,当所有线程完成当前阶段后,需要等待所有线程都到达屏障点,然后一起开始下一阶段的计算。
    数据合并或汇总:多个线程各自处理一部分数据,处理完成后在屏障点等待,直到所有线程都完成处理,然后一起进行全局数据的合并或结果汇总。
    游戏或模拟环境中的回合制同步:在多线程游戏中,各线程代表不同的角色或实体,需要在每一轮结束时同步状态,等待所有参与者都准备好后开始下一轮。
    

    工作原理: CyclicBarrier 内部同样维护一个计数器,但其值始终等于参与线程的数量。每个参与线程调用 await() 方法时,计数器减一。当计数器减至零时,屏障开放,所有之前因调用 await() 而阻塞的线程将被释放,同时触发一个可选的栅栏动作(通过构造时提供的 Runnable 实现)。随后计数器被重置到初始值,准备下一轮的同步等待。

    特点:

    可重用:CyclicBarrier 可以重复使用,每当所有线程都到达屏障点并完成栅栏动作后,计数器会自动重置,可以用于下一轮的同步。
    循环等待:CyclicBarrier 具有循环等待的特性,线程可以在完成一次同步后继续参与下一次同步。
    栅栏动作:CyclicBarrier 提供了在所有线程到达屏障点时执行额外操作的能力,这是一个可选的回调机制,用于在同步点执行一些共同的操作,如数据交换、状态更新等。
    

    总结来说,CountDownLatch 和 CyclicBarrier 都是用于线程同步的工具,但它们的应用场景和工作方式有所不同。CountDownLatch 通常用于一次性等待多个线程完成某项任务后继续执行,而 CyclicBarrier 则更适用于一组线程反复在特定点同步,执行一系列相互依赖的任务,并且在每次同步后可以复用。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 4月20日
  • 已采纳回答 4月12日
  • 创建了问题 4月12日