image

编辑人: 流年絮语

calendar2025-07-20

message7

visits91

45天强化提升:Java并发工具类CyclicBarrier与CountDownLatch实战精讲

在Java编程中,多线程编程是一个重要且复杂的主题。特别是在大型应用和高并发场景下,如何有效地管理和控制线程成为了一项关键技术。本文将深入探讨Java并发工具类中的CyclicBarrier与CountDownLatch,并通过赛车比赛/任务分治实战案例来解析多线程同步机制。

一、CyclicBarrier与CountDownLatch概述

  1. CyclicBarrier

CyclicBarrier是Java并发包中的一个同步工具类,它允许一组线程互相等待,直到所有线程都到达一个屏障点。CyclicBarrier特别适用于将一个任务拆分成多个子任务,每个子任务由一个线程执行,当所有子任务都完成后,再执行主任务。

主要特点:

  • 可以重复使用,即屏障可以“循环”使用。
  • 当所有线程都到达屏障点时,可以执行一个预定义的动作。
  1. CountDownLatch

CountDownLatch是另一个Java并发工具类,它允许一个或多个线程等待其他线程完成后再继续执行。CountDownLatch通过一个计数器来实现,计数器的初始值表示需要等待的线程数量。每当一个线程完成了任务,计数器就减1。当计数器的值变为0时,表示所有线程都已完成任务,等待的主线程可以继续执行。

主要特点:

  • 不能重复使用,计数器一旦减到0,就不能再重置。
  • 适用于一个线程等待多个线程完成任务的场景。

二、CyclicBarrier与CountDownLatch对比

  1. 使用场景:CyclicBarrier适用于将任务拆分成多个子任务的场景,而CountDownLatch适用于一个线程等待多个线程完成任务的场景。
  2. 可重用性:CyclicBarrier可以重复使用,而CountDownLatch一旦计数器减到0,就不能再重置。
  3. 等待机制:CyclicBarrier中的线程会互相等待,直到所有线程都到达屏障点;而CountDownLatch中的主线程会等待其他线程完成任务。

三、实战案例:赛车比赛与任务分治

  1. 赛车比赛案例

假设有一个赛车比赛,每辆赛车都是一个线程。比赛开始前,所有赛车需要准备好。我们可以使用CyclicBarrier来实现这个场景。当所有赛车都准备好后,比赛开始。

代码示例:

import java.util.concurrent.CyclicBarrier;

public class Racing {
    public static void main(String[] args) {
        int carCount = 5; // 赛车数量
        CyclicBarrier barrier = new CyclicBarrier(carCount, () -> {
            System.out.println("所有赛车已准备好,比赛开始!");
        });

        for (int i = 0; i < carCount; i++) {
            new Thread(new Car(barrier), "Car-" + (i + 1)).start();
        }
    }
}

class Car implements Runnable {
    private CyclicBarrier barrier;

    public Car(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + " 正在准备...");
            Thread.sleep((long) (Math.random() * 1000)); // 模拟准备时间
            System.out.println(Thread.currentThread().getName() + " 准备完毕!");
            barrier.await(); // 等待所有赛车准备好
            System.out.println(Thread.currentThread().getName() + " 开始比赛!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  1. 任务分治案例

假设有一个大任务需要拆分成多个小任务,每个小任务由一个线程执行。当所有小任务都完成后,再执行主任务。我们可以使用CountDownLatch来实现这个场景。

代码示例:

import java.util.concurrent.CountDownLatch;

public class TaskDivision {
    public static void main(String[] args) throws InterruptedException {
        int taskCount = 5; // 子任务数量
        CountDownLatch latch = new CountDownLatch(taskCount);

        for (int i = 0; i < taskCount; i++) {
            new Thread(new SubTask(latch), "SubTask-" + (i + 1)).start();
        }

        latch.await(); // 等待所有子任务完成
        System.out.println("所有子任务已完成,执行主任务!");
    }
}

class SubTask implements Runnable {
    private CountDownLatch latch;

    public SubTask(CountDownLatch latch) {
        this.latch = latch;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + " 正在执行...");
            Thread.sleep((long) (Math.random() * 1000)); // 模拟执行时间
            System.out.println(Thread.currentThread().getName() + " 执行完毕!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            latch.countDown(); // 子任务完成,计数器减1
        }
    }
}

四、总结

本文深入探讨了Java并发工具类中的CyclicBarrier与CountDownLatch,并通过赛车比赛/任务分治实战案例来解析多线程同步机制。在实际开发中,根据不同的场景选择合适的同步工具类,可以有效提高程序的性能和稳定性。希望本文能对大家在Java多线程编程方面有所帮助。

喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!

创作类型:
原创

本文链接:45天强化提升:Java并发工具类CyclicBarrier与CountDownLatch实战精讲

版权声明:本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。
分享文章
share