Java多线程信号同步工具详解:CountDownLatch、CyclicBarrier与Semaphore

顾星河
顾星河
发布时间:2026-10-15| 5人浏览过
原创

在Java多线程开发中,协调多个线程的执行顺序与状态至关重要。JDK1.5引入了CountDownLatch、CyclicBarrier和Semaphore等辅助类,分别解决了多任务汇总等待、固定线程屏障等待以及资源信号量控制等问题。掌握这些工具是构建高效并发程序的基础。

基于时间维度的任务等待:CountDownLatch

当主线程需要等待多个子线程完成特定任务(如数据分季度统计后汇总)时,CountDownLatch是最常用的选择。它的核心逻辑是“减少计数”,即初始化时设定参与协作的线程总数,每个线程完成任务后调用countDown()减少计数,主线程调用await()阻塞直至计数归零。

第1步:初始化CountDownLatch实例

根据参与的线程数量初始化计数器。例如,若有6个线程协作,构造函数参数即为6。

第2步:启动子线程并执行任务

创建线程池或新Thread,在线程内部执行业务逻辑。关键点是在任务执行完毕后,必须调用 countDownLatch.countDown(),表示该线程已完成贡献。

第3步:主线程等待并完成汇总

在主线程中调用 countDownLatch.await()。该方法会阻塞当前线程,直到所有子线程都调用了countDown使计数变为0。一旦计数归零,主线程继续执行后续逻辑。

public static void main(String[] args) throws InterruptedException {
    final int NUM = 6;
    //定义总数量;
    CountDownLatch countDownLatch = new CountDownLatch(NUM);
    for (int i = 0; i < NUM; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "线程,已执行!");
            //减少计数
            countDownLatch.countDown();
        }, String.valueOf(i + 1)).start();
    }
    //等待所有任务完成
    countDownLatch.await();
    System.out.println("所有线程任务已经执行完成!");
}

基于屏障点的循环等待:CyclicBarrier

CyclicBarrier(循环栅栏)适用于一组线程相互等待,当所有线程都到达某个公共障碍点(barrier)时,再同时继续执行。与CountDownLatch不同,CyclicBarrier可以重用,且允许指定当屏障点突破时需执行的一个Runnable动作。

第1步:设置屏障点数与回调动作

初始化CyclicBarrier,第一个参数为参与等待的线程数,第二个参数为一个 Runnable,用于在所有线程到达屏障后触发后续统一逻辑(如结果汇总)。

第2步:线程到达屏障点

每个线程在执行完阶段性任务后,调用 cyclicBarrier.await()。此方法会阻塞该线程,直到其他线程也到达此处。若中途有线程中断或超时,可能导致 BrokenBarrierException。

第3步:执行回调与继续运行

当所有线程均到达屏障,屏障点被打开,首先执行预设的回调任务,随后所有等待线程解除阻塞继续向下执行。

public static void main(String[] args) {
    final int NUM = 6;
    //定义循环数量及循环完成后的任务(Runnable接口实现);
    CyclicBarrier cyclicBarrier = new CyclicBarrier(NUM, () -> {
        System.out.println("所有线程任务已经执行完成!");
    });
    for (int i = 0; i < NUM; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "线程,已执行!");
            try {
                //等待点或障碍点,等待所有任务完成,
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }, String.valueOf(i + 1)).start();
    }
}

基于信号量的并发控制:Semaphore

Semaphore(信号灯)主要用于控制同时访问某一资源的线程数量,常用于限流或保护资源。它维护了一组许可(permit),线程需要通过 acquire() 获取许可才能进入临界区,使用完后通过 release() 归还许可,供其他线程使用。

第1步:初始化信号量

指定可用信号量的数量。例如,限制最大并发数为3,则 Semaphore semaphore = new Semaphore(3)。

第2步:获取信号量

线程尝试执行时,调用 semaphore.acquire()。如果当前无可用信号量,线程将阻塞等待,直到有其他线程释放信号量。

第3步:执行业务逻辑并释放信号量

获得许可后执行具体代码。务必在 finally 块中调用 semaphore.release(),确保即使发生异常也能归还信号量,避免死锁或资源耗尽。

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/*信号灯
* 6个线程,抢占三个信号
* */
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);
        for (int i = 0; i < 6; i++) {
            new Thread(() -> {
                try {
                    //获取信号
                    semaphore.acquire();
                    System.out.println("线程:" + Thread.currentThread().getName() + "----获取信号");
                    int time = new Random().nextInt(5);
                    System.out.println(("线程:" + Thread.currentThread().getName() + "----休眠" + time + "s!"));
                    TimeUnit.SECONDS.sleep(time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //    释放信号
                    System.out.println("线程:" + Thread.currentThread().getName() + "---释放信号");
                    semaphore.release();
                }
            }, String.valueOf(i + 1)).start();
        }
    }
}

在实际运行中,假设初始有3个信号量,前3个线程(如线程4、1、3)可立即获取信号并执行;后3个线程(如2、5、6)则处于等待状态。一旦某个线程执行完毕并调用release(),等待队列中的线程将获得信号继续执行,从而实现动态的并发控制。

总结

Java提供了丰富的线程协作工具:CountDownLatch适合一次性等待多个事件完成;CyclicBarrier适合固定线程数的多点同步与回调处理;Semaphore适合控制资源并发访问上限。开发者应根据具体的业务场景选择最合适的同步机制,以确保多线程程序的稳定性与高效性。

以上就是Java详解多线程协作作业之信号同步的详细内容,更多关于Java多线程并发编程的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。