Java 中 CyclicBarrier 和 CountDownLatch 的区别

简介: 【8月更文挑战第22天】

概述

CyclicBarrierCountDownLatch 是 Java 中用于线程同步的两个并发工具。虽然这两个类都用于协调线程,但它们有不同的目的和用法。

CyclicBarrier

CyclicBarrier 是一个可重复使用的同步点,允许一组线程等待直到所有线程都到达该点。一旦所有线程都到达该点,屏障就会解除,所有线程都可以继续执行。

CountDownLatch

CountDownLatch 是一个一次性同步点,允许一个或多个线程等待直到一个计数器达到零。一旦计数器达到零,所有等待的线程都可以继续执行。

主要区别

  • 可重复使用性: CyclicBarrier 是可重复使用的,这意味着它可以在线程到达屏障后重置并再次使用。CountDownLatch 是不可重复使用的,一旦计数器达到零,它就完成了。
  • 等待条件: CyclicBarrier 等待所有线程到达屏障。CountDownLatch 等待计数器达到零。
  • 线程唤醒: CyclicBarrier 一次唤醒所有等待的线程。CountDownLatch 逐个唤醒等待的线程。

示例

以下示例演示了 CyclicBarrierCountDownLatch 之间的区别:

CyclicBarrier

public class CyclicBarrierExample {
   

    public static void main(String[] args) {
   
        // 创建一个具有 3 个参与者的 CyclicBarrier
        CyclicBarrier barrier = new CyclicBarrier(3);

        // 创建 3 个线程
        Thread t1 = new Thread(() -> {
   
            try {
   
                // 线程 1 到达屏障
                barrier.await();
                System.out.println("线程 1 已到达屏障。");
            } catch (Exception e) {
   
                e.printStackTrace();
            }
        });

        Thread t2 = new Thread(() -> {
   
            try {
   
                // 线程 2 到达屏障
                barrier.await();
                System.out.println("线程 2 已到达屏障。");
            } catch (Exception e) {
   
                e.printStackTrace();
            }
        });

        Thread t3 = new Thread(() -> {
   
            try {
   
                // 线程 3 到达屏障
                barrier.await();
                System.out.println("线程 3 已到达屏障。");
            } catch (Exception e) {
   
                e.printStackTrace();
            }
        });

        // 启动线程
        t1.start();
        t2.start();
        t3.start();
    }
}

输出:

线程 1 已到达屏障。
线程 2 已到达屏障。
线程 3 已到达屏障。

在这个示例中,三个线程都到达屏障后,屏障解除,所有线程继续执行。

CountDownLatch

public class CountDownLatchExample {
   

    public static void main(String[] args) {
   
        // 创建一个具有 3 个计数的 CountDownLatch
        CountDownLatch latch = new CountDownLatch(3);

        // 创建 3 个线程
        Thread t1 = new Thread(() -> {
   
            try {
   
                // 线程 1 完成任务
                latch.countDown();
                System.out.println("线程 1 已完成任务。");
            } catch (Exception e) {
   
                e.printStackTrace();
            }
        });

        Thread t2 = new Thread(() -> {
   
            try {
   
                // 线程 2 完成任务
                latch.countDown();
                System.out.println("线程 2 已完成任务。");
            } catch (Exception e) {
   
                e.printStackTrace();
            }
        });

        Thread t3 = new Thread(() -> {
   
            try {
   
                // 线程 3 完成任务
                latch.countDown();
                System.out.println("线程 3 已完成任务。");
            } catch (Exception e) {
   
                e.printStackTrace();
            }
        });

        // 启动线程
        t1.start();
        t2.start();
        t3.start();

        // 等待所有线程完成任务
        try {
   
            latch.await();
            System.out.println("所有线程已完成任务。");
        } catch (Exception e) {
   
            e.printStackTrace();
        }
    }
}

输出:

线程 1 已完成任务。
线程 2 已完成任务。
线程 3 已完成任务。
所有线程已完成任务。

在这个示例中,三个线程完成任务后,计数器达到零,所有等待的线程继续执行。

总结

CyclicBarrierCountDownLatch 都是有用的并发工具,用于协调线程。CyclicBarrier 用于同步一组线程,直到它们都到达一个点,而 CountDownLatch 用于同步一个或多个线程,直到一个计数器达到零。选择哪一个工具取决于任务的需要。

目录
相关文章
|
16天前
|
XML JSON 前端开发
Java @RequestParam和@RequestBody的区别是什么?
【8月更文挑战第28天】Java @RequestParam和@RequestBody的区别是什么?
27 5
|
23天前
|
Java
Java 中 notify() 和 notifyAll() 的区别
【8月更文挑战第22天】
41 4
|
22天前
|
存储 安全 Java
Java 中 ArrayList 和 HashSet 的区别
【8月更文挑战第23天】
34 2
|
22天前
|
Java 调度
|
22天前
|
存储 安全 Java
Java 中数组和 ArrayList 的区别
【8月更文挑战第23天】
27 1
|
21天前
|
Java 程序员
详解Java中的抽象类与接口的区别
【8月更文挑战第24天】
21 0
|
安全 Java
java中CyclicBarrier的使用
java中CyclicBarrier的使用
|
11天前
|
监控 Java 调度
【Java学习】多线程&JUC万字超详解
本文详细介绍了多线程的概念和三种实现方式,还有一些常见的成员方法,CPU的调动方式,多线程的生命周期,还有线程安全问题,锁和死锁的概念,以及等待唤醒机制,阻塞队列,多线程的六种状态,线程池等
73 6
【Java学习】多线程&JUC万字超详解
|
4天前
|
Java 调度 开发者
Java并发编程:深入理解线程池
在Java的世界中,线程池是提升应用性能、实现高效并发处理的关键工具。本文将深入浅出地介绍线程池的核心概念、工作原理以及如何在实际应用中有效利用线程池来优化资源管理和任务调度。通过本文的学习,读者能够掌握线程池的基本使用技巧,并理解其背后的设计哲学。