当前位置: 首页 > news >正文

CyclicBarrier CountDownLatch

CyclicBarrierCountDownLatch 是 Java 并发包(java.util.concurrent)中的两个常用同步工具,它们用于协调多个线程的执行。然而,它们在设计和使用方式上有着显著的区别,特别是在可重复使用方面。

1. CyclicBarrier 是可重复使用的

CyclicBarrier 是一个循环的屏障(cyclic),其主要功能是让一组线程到达某个屏障点后再同时继续执行。当所有线程都到达屏障时,它会自动重置并进入下一轮等待,这就是它“可重复使用”的特性。它的重用性源于每次线程到达屏障后,会自动重置计数器,并允许再次使用。

  • 特点

    • 复用性:一旦所有线程都到达屏障并通过,屏障自动重置,允许这些线程或其他线程再次使用该屏障进行同步。这意味着 CyclicBarrier 可以在多个循环或阶段中重复使用。
    • 栅栏动作CyclicBarrier 还允许在线程到达屏障时执行一个栅栏动作(可选),该动作可以是某个特定的任务,如日志记录、数据汇总等。
  • 示例

    CyclicBarrier barrier = new CyclicBarrier(3); // 3个线程需要到达屏障Runnable task = () -> {try {System.out.println(Thread.currentThread().getName() + " 到达屏障");barrier.await();  // 等待其他线程到达屏障System.out.println(Thread.currentThread().getName() + " 通过屏障");} catch (Exception e) {e.printStackTrace();}
    };for (int i = 0; i < 3; i++) {new Thread(task).start();
    }// CyclicBarrier 可以重复使用,允许继续同步新的线程到达屏障
    // 运行结果
    Thread-2 到达屏障
    Thread-1 到达屏障
    Thread-0 到达屏障
    Thread-1 通过屏障
    Thread-2 通过屏障
    Thread-0 通过屏障
    

    这里,当所有 3 个线程都到达 barrier.await() 时,屏障将被释放,线程继续执行。在下一轮中,这些线程可以再次使用同一个 CyclicBarrier

2. CountDownLatch 是一次性的

CountDownLatch 是一个倒计时锁存器,它用于让一个或多个线程等待,直到其他线程完成某个操作。当计数器到达 0 时,所有等待的线程被释放,之后 CountDownLatch 就无法再次使用了。

  • 特点

    • 一次性使用CountDownLatch 是一次性的。一旦计数器从初始值倒数到 0,锁存器不能重置,也不能重新计数。如果需要再次使用,只能创建一个新的 CountDownLatch 实例。
    • 没有栅栏动作CountDownLatch 不像 CyclicBarrier 那样有一个统一的屏障动作,它只是一个简单的计数器,控制多个线程的同步。
  • 示例

    CountDownLatch latch = new CountDownLatch(3); // 初始计数为 3Runnable task = () -> {System.out.println(Thread.currentThread().getName() + " 完成任务");latch.countDown(); // 每个线程完成任务后调用 countDown()
    };for (int i = 0; i < 3; i++) {new Thread(task).start();
    }try {latch.await();  // 等待计数器变为 0System.out.println("所有任务完成,继续执行主线程");
    } catch (InterruptedException e) {e.printStackTrace();
    }// 运行结果:
    Thread-2 完成任务
    Thread-1 完成任务
    Thread-0 完成任务
    所有任务完成,继续执行主线程
    

    在这个例子中,CountDownLatch 初始计数为 3,表示需要 3 个线程完成任务。当计数器变为 0 时,主线程继续执行。然而,CountDownLatch 在计数变为 0 后无法重置,不能再次使用。

3. 为什么 CyclicBarrier 可重复使用,而 CountDownLatch 是一次性的?

  • 设计目的

    • CyclicBarrier:设计的目的是在循环或阶段性任务中使用,它允许同一批线程在不同的阶段都同步等待,完成一轮后可以自动重置并继续下一轮,因此它是循环使用的工具。
    • CountDownLatch:设计目的是让某个线程等待一组操作完成后继续执行,常用于一次性事件(如系统初始化、任务完成的信号)。它的计数一旦减为 0,表示操作已经完成,之后不能重新计数,因此是一次性的工具
  • 实现机制

    • CyclicBarrier:每当线程到达屏障并通过时,屏障自动重置,允许再次使用。其内部维护一个计数器和栅栏代(generation)来实现多次复用。
    • CountDownLatch:计数器一旦减到 0,锁存器就完成任务,无法重置,除非重新创建一个新的实例。

4. 使用场景的差异

  • CyclicBarrier 使用场景

    • 多线程分阶段处理任务时,每个阶段都需要所有线程在某个点上同步。例如,在一个并行算法中,多个线程需要在每个阶段结束时进行同步。
  • CountDownLatch 使用场景

    • 在某些初始化操作中,主线程需要等待其他线程完成后继续执行。例如,一个主线程等待几个工作线程完成任务,然后才继续执行。

总结

  • CyclicBarrier 可重复使用:它的设计允许在多个循环或阶段中重复使用,当一组线程到达屏障后,屏障会自动重置,进入下一轮等待。
  • CountDownLatch 是一次性的:它的计数器一旦到达 0,就无法再次使用,只能用于一次性任务协调。如果需要再次使用,必须创建新的实例。

http://www.mrgr.cn/news/24832.html

相关文章:

  • Elemnt-UI + 递归组件实现后台管理系统左侧菜单
  • 1.任务的创建与状态
  • Could not resolve type alias错误
  • Unity Hub自动安装指定版本Unity的Android开发环境
  • MySQL之安装与基础知识
  • 408算法题leetcode--第一天
  • GC日志详细解析,非常详细GC(20) Pause Young (Normal) (G1 Evacuation Pause)
  • Python自动化办公2.0
  • 【数据库】详解基本SQL语句用法
  • 基于SpringBoot+Vue+MySQL的校园生活服务平台
  • 为什么 1T 的硬盘容量只有 931G?真相在这里!
  • 【重学 MySQL】二十四、笛卡尔积的错误和正确的多表查询
  • [机器学习]决策树
  • C++系列-谓词predicate
  • 使用Python下载文件的简易指南
  • unity3d入门教程一
  • 如何 吧一个 一维数组 切分成相同等分,一维数组作为lstm的输入(三维数据)的数据预处理
  • STM32 WDG看门狗
  • 【学习笔记】手写Tomcat 二
  • C语言练习题3