Java中的J.U.C并发工具类详解
字数 1284 2025-11-04 20:48:20

Java中的J.U.C并发工具类详解

一、J.U.C概述
J.U.C(java.util.concurrent)是Java提供的并发编程工具包,包含解决并发问题的三大类组件:

  1. 原子类(Atomic) - 线程安全的原子操作类
  2. 锁机制(Locks) - 比synchronized更灵活的锁
  3. 并发集合(Collections) - 线程安全的集合容器
  4. 线程池(Executor) - 线程管理和调度
  5. 同步工具(Tools) - 控制线程执行的工具类

二、CountDownLatch(倒计时门闩)

  1. 核心作用:让一个或多个线程等待其他线程完成操作

  2. 实现原理

    • 内部维护一个计数器,初始化时设置等待的线程数
    • 每个线程完成时调用countDown()使计数器减1
    • 当计数器为0时,等待的线程被唤醒
  3. 代码示例

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3); // 初始计数器为3
        
        for (int i = 1; i <= 3; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " 完成任务");
                latch.countDown(); // 计数器减1
            }, "线程" + i).start();
        }
        
        latch.await(); // 主线程等待,直到计数器为0
        System.out.println("所有线程完成任务,主线程继续执行");
    }
}

三、CyclicBarrier(循环屏障)

  1. 核心作用:让一组线程相互等待,达到共同屏障点后再继续执行

  2. 与CountDownLatch的区别

    • CountDownLatch是一次性的,CyclicBarrier可重复使用
    • CountDownLatch由主线程等待,CyclicBarrier是线程间相互等待
  3. 代码示例

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3, () -> {
            System.out.println("所有线程到达屏障,执行屏障动作");
        });
        
        for (int i = 1; i <= 3; i++) {
            new Thread(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 到达屏障");
                    barrier.await(); // 等待其他线程
                    System.out.println(Thread.currentThread().getName() + " 继续执行");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "线程" + i).start();
        }
    }
}

四、Semaphore(信号量)

  1. 核心作用:控制同时访问特定资源的线程数量

  2. 两种模式

    • 公平模式:按申请顺序获取许可
    • 非公平模式:抢占式获取许可
  3. 代码示例

public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3); // 允许3个线程同时访问
        
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire(); // 获取许可
                    System.out.println(Thread.currentThread().getName() + " 获取资源");
                    Thread.sleep(2000); // 模拟资源使用
                    System.out.println(Thread.currentThread().getName() + " 释放资源");
                    semaphore.release(); // 释放许可
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "线程" + i).start();
        }
    }
}

五、Exchanger(交换器)

  1. 核心作用:用于两个线程间交换数据

  2. 执行流程

    • 线程A执行exchange()方法后阻塞,等待线程B
    • 线程B执行exchange()方法后,双方交换数据并继续执行
  3. 代码示例

public class ExchangerDemo {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<>();
        
        new Thread(() -> {
            try {
                String dataA = "数据A";
                System.out.println("线程A发送: " + dataA);
                String result = exchanger.exchange(dataA);
                System.out.println("线程A收到: " + result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        
        new Thread(() -> {
            try {
                String dataB = "数据B";
                System.out.println("线程B发送: " + dataB);
                String result = exchanger.exchange(dataB);
                System.out.println("线程B收到: " + result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

六、Phaser(阶段器)

  1. 核心作用:更灵活的可重用同步屏障,支持动态调整参与线程数

  2. 核心概念

    • 阶段(Phase):从0开始编号,完成所有线程后阶段号递增
    • 注册(Register):动态增加或减少参与线程数
  3. 代码示例

public class PhaserDemo {
    public static void main(String[] args) {
        Phaser phaser = new Phaser(3) { // 初始3个参与线程
            @Override
            protected boolean onAdvance(int phase, int registeredParties) {
                System.out.println("阶段 " + phase + " 完成");
                return registeredParties == 0; // 返回true终止Phaser
            }
        };
        
        for (int i = 1; i <= 3; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " 完成阶段0");
                phaser.arriveAndAwaitAdvance(); // 等待其他线程
                
                System.out.println(Thread.currentThread().getName() + " 完成阶段1");
                phaser.arriveAndAwaitAdvance();
                
                phaser.arriveAndDeregister(); // 完成任务并注销
            }, "线程" + i).start();
        }
    }
}

七、工具类对比总结

工具类 核心功能 可重用性 特点
CountDownLatch 等待指定数量任务完成 一次性使用,主线程等待
CyclicBarrier 线程间相互等待 可重复使用,支持屏障动作
Semaphore 控制资源访问数量 支持公平/非公平模式
Exchanger 线程间数据交换 仅支持两个线程交换
Phaser 分阶段任务同步 最灵活,支持动态调整

八、使用场景分析

  1. CountDownLatch:主线程等待所有子任务完成
  2. CyclicBarrier:多线程计算,合并计算结果
  3. Semaphore:数据库连接池限流
  4. Exchanger:两个线程间数据校对
  5. Phaser:复杂的多阶段任务协调

这些工具类提供了比wait/notify更高级的线程协作方式,能够简化复杂并发场景的开发。

Java中的J.U.C并发工具类详解 一、J.U.C概述 J.U.C(java.util.concurrent)是Java提供的并发编程工具包,包含解决并发问题的三大类组件: 原子类(Atomic) - 线程安全的原子操作类 锁机制(Locks) - 比synchronized更灵活的锁 并发集合(Collections) - 线程安全的集合容器 线程池(Executor) - 线程管理和调度 同步工具(Tools) - 控制线程执行的工具类 二、CountDownLatch(倒计时门闩) 核心作用 :让一个或多个线程等待其他线程完成操作 实现原理 : 内部维护一个计数器,初始化时设置等待的线程数 每个线程完成时调用countDown()使计数器减1 当计数器为0时,等待的线程被唤醒 代码示例 : 三、CyclicBarrier(循环屏障) 核心作用 :让一组线程相互等待,达到共同屏障点后再继续执行 与CountDownLatch的区别 : CountDownLatch是一次性的,CyclicBarrier可重复使用 CountDownLatch由主线程等待,CyclicBarrier是线程间相互等待 代码示例 : 四、Semaphore(信号量) 核心作用 :控制同时访问特定资源的线程数量 两种模式 : 公平模式:按申请顺序获取许可 非公平模式:抢占式获取许可 代码示例 : 五、Exchanger(交换器) 核心作用 :用于两个线程间交换数据 执行流程 : 线程A执行exchange()方法后阻塞,等待线程B 线程B执行exchange()方法后,双方交换数据并继续执行 代码示例 : 六、Phaser(阶段器) 核心作用 :更灵活的可重用同步屏障,支持动态调整参与线程数 核心概念 : 阶段(Phase):从0开始编号,完成所有线程后阶段号递增 注册(Register):动态增加或减少参与线程数 代码示例 : 七、工具类对比总结 | 工具类 | 核心功能 | 可重用性 | 特点 | |-------|---------|---------|------| | CountDownLatch | 等待指定数量任务完成 | 否 | 一次性使用,主线程等待 | | CyclicBarrier | 线程间相互等待 | 是 | 可重复使用,支持屏障动作 | | Semaphore | 控制资源访问数量 | 是 | 支持公平/非公平模式 | | Exchanger | 线程间数据交换 | 是 | 仅支持两个线程交换 | | Phaser | 分阶段任务同步 | 是 | 最灵活,支持动态调整 | 八、使用场景分析 CountDownLatch :主线程等待所有子任务完成 CyclicBarrier :多线程计算,合并计算结果 Semaphore :数据库连接池限流 Exchanger :两个线程间数据校对 Phaser :复杂的多阶段任务协调 这些工具类提供了比wait/notify更高级的线程协作方式,能够简化复杂并发场景的开发。