并发工具类
并发工具类位于 java.util.concurrent 包,用于协调多线程执行。
CountDownLatch(倒计时锁)
作用
一个线程等待其他多个线程完成。
使用示例
Java
// 主线程等待 3 个工作线程完成
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
// 执行任务
System.out.println(Thread.currentThread().getName() + " 完成");
} finally {
latch.countDown(); // 计数减 1
}
}).start();
}
latch.await(); // 主线程等待,计数归零后继续
System.out.println("所有工作线程完成");
特点
- 计数器递减,归零触发 await() 继续
- 一次性使用,不可重置
- await() 可设置超时
适用场景
- 主线程等待多个子任务完成
- 服务启动等待多个组件就绪
CyclicBarrier(循环屏障)
作用
多个线程互相等待,都到达屏障点后一起继续。
使用示例
Java
// 3 个线程互相等待,都到达后一起继续
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有线程到达屏障,执行汇总");
});
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
System.out.println("第一阶段完成");
barrier.await(); // 等待其他线程
System.out.println("第二阶段开始");
barrier.await(); // 等待其他线程(可循环使用)
} catch (Exception e) {}
}).start();
}
特点
- 计数器可重置,循环使用
- 可指定屏障动作:所有线程到达后执行回调
- await() 可设置超时
适用场景
- 多线程分阶段并行计算
- 多线程定时汇总
Semaphore(信号量)
作用
控制同时访问资源的线程数量,用于限流。
使用示例
Java
// 允许 3 个线程同时访问
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
semaphore.acquire(); // 获取许可(最多 3 个同时持有)
System.out.println(Thread.currentThread().getName() + " 访问资源");
Thread.sleep(2000);
} finally {
semaphore.release(); // 释放许可
}
}).start();
}
特点
- 可设置公平/非公平模式
- acquire() 可设置超时
- 可动态调整许可数量
适用场景
- 限流:控制并发访问数量
- 资源池:如数据库连接池控制
Exchanger(交换器)
作用
两个线程交换数据。
使用示例
Java
Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
try {
String data = "数据A";
String received = exchanger.exchange(data); // 交换
System.out.println("收到:" + received);
} catch (InterruptedException e) {}
}).start();
new Thread(() -> {
try {
String data = "数据B";
String received = exchanger.exchange(data); // 交换
System.out.println("收到:" + received);
} catch (InterruptedException e) {}
}).start();
Phaser(阶段器)
作用
CyclicBarrier 的增强版,支持动态调整参与者数量。
使用示例
Java
Phaser phaser = new Phaser(3); // 3 个参与者
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("阶段 1 完成");
phaser.arriveAndAwaitAdvance(); // 等待所有线程到达
System.out.println("阶段 2 完成");
phaser.arriveAndAwaitAdvance();
// 动态注销(不再参与后续阶段)
phaser.arriveAndDeregister();
}).start();
}
三者对比
| 特性 | CountDownLatch | CyclicBarrier | Semaphore |
|---|---|---|---|
| 作用 | 一等多 | 多等多 | 控制并发数 |
| 计数方向 | 递减 | 递增到阈值 | 不计数 |
| 是否可重用 | ❌ 一次性 | ✅ 可循环 | ✅ 可复用 |
| 等待触发 | 计数归零 | 达到指定数量 | 获取许可 |
| 适用场景 | 等待子任务完成 | 分阶段协作 | 并发限流 |
要点总结
- CountDownLatch:一等多,计数递减,一次性
- CyclicBarrier:多等多,可循环,支持屏障动作
- Semaphore:控制并发数量,可复用
- Exchanger:两个线程交换数据
- Phaser:动态调整参与者,支持注销
- CountDownLatch 用于等待子任务完成
- CyclicBarrier 用于分阶段协作
- Semaphore 用于限流控制
📝 发现内容有误?点击此处直接编辑