├── 五、线程通信
│ ├── wait / notify

│ ├── Condition
│ ├── CountDownLatch
| Object | Condition |
|---|---|
| wait() | await() |
| notify() | signal() |
| notifyAll() | signalAll() |
ReentrantLock
synchronized + wait/notify
只能有一个等待队列:
锁对象
|
|-- wait线程1
|-- wait线程2
|-- wait线程3
而 Condition 可以创建多个等待队列:
ReentrantLock
|
+-- Condition A
| |
| +-- 等待线程
|
+-- Condition B
|
+-- 等待线程
可以精确唤醒不同类型线程。
│ ├──Semaphore

Semaphore 是 Java JUC(java.util.concurrent)提供的信号量工具,用于:
控制同时访问某个资源的线程数量。
Semaphore 内部维护一个许可证(permit)数量:
例如:
Semaphore semaphore = new Semaphore(3);表示:
许可证数量 = 3线程进入:
acquire()获取许可证:
3 线程A获取 2 线程B获取 1 线程C获取 0 线程D等待释放:
release()归还许可证:
0 release() 1 线程D可以进入
acquire() 获取许可证:
release() 释放许可证:
tryAcquire() 尝试获取:
│ ├──CyclicBarrier

CountDownLatch 是 Java JUC(java.util.concurrent)提供的线程同步工具。
让一个或多个线程等待其他线程完成后再继续执行。
CountDownLatch 内部维护一个计数器:
CountDownLatch(3)表示:
count = 3有 3 个任务需要完成。
每完成一个:
countDown()计数减一:
3 | 任务1完成 | 2 | 任务2完成 | 1 | 任务3完成 | 0当:
count == 0等待的线程继续执行。
CountDownLatch(3)|
| | |
配置加载 缓存加载 数据库加载
↓ ↓ ↓
countDown() countDown() countDown()
count = 0
↓
主线程继续启动
import java.util.concurrent.CountDownLatch;
public class Test {
public static void main(String\[\] args)
throws InterruptedException {
CountDownLatch latch =
new CountDownLatch(3);
for(int i=1;i<=3;i++){
new Thread(() -> {
System.out.println(
Thread.currentThread().getName()
+" 执行任务"
);
try {
Thread.sleep(1000);
} catch(Exception e){
}
//任务完成
latch.countDown();
}).start();
}
//等待所有任务完成
latch.await();
System.out.println(
"所有任务完成,主线程继续"
);
}
}
│ ├── Phaser

Phaser 是 Java JUC(java.util.concurrent)提供的多阶段线程同步工具。
java.util.concurrent.Phaser
JDK 7 引入。
让多个线程分阶段执行任务,每个阶段完成后等待其他线程,然后进入下一阶段。
CyclicBarrier + CountDownLatch 的增强版。
CountDownLatch
- 只能等待一次
- 数量固定
例如:
任务1完成 任务2完成 任务3完成 count = 0 结束不能重新开始。
CyclicBarrier:
- 可以循环
- 但是参与线程数量固定
而 Phaser:
- 支持多个阶段
- 支持动态增加/减少线程
- 每个阶段可以执行不同逻辑
│ └── Exchanger
Exchanger 是 Java JUC(java.util.concurrent)提供的线程间数据交换工具。
让两个线程在某个同步点交换数据。
线程A 手里有数据A
线程B 手里有数据B
↓
Exchanger
↓
线程A 得到数据B
线程B 得到数据A
exchange() exchange(timeout)
交换数据:
String result =
exchanger.exchange("hello");
java
import java.util.concurrent.Exchanger;
public class Test {
public static void main(String[] args) {
Exchanger<String> exchanger =
new Exchanger<>();
new Thread(() -> {
try {
String data =
"生产的数据";
System.out.println(
"线程A发送:"
+ data
);
String result =
exchanger.exchange(data);
System.out.println(
"线程A收到:"
+ result
);
} catch(Exception e){
}
}).start();
new Thread(() -> {
try {
String data =
"消费的数据";
System.out.println(
"线程B发送:"
+ data
);
String result =
exchanger.exchange(data);
System.out.println(
"线程B收到:"
+ result
);
} catch(Exception e){
}
}).start();
}
}
| 特点 | 说明 |
|---|---|
| 核心作用 | 两个线程在同步点交换数据 |
| 参与线程数量 | 固定两个线程进行交换 |
| 交换方式 | 一方提交数据,等待另一方提交数据,然后互换 |
| 是否阻塞 | 是,没有另一方到达时会阻塞等待 |
| 是否可重复使用 | ✅ 可以,多次调用 exchange() |
| 是否支持超时 | ✅ 支持 |
| 是否支持中断 | ✅ 支持线程中断 |
| 数据类型 | 泛型,可以交换任意对象 |
| 是否基于 AQS | ❌ 不是 |
| 底层实现 | CAS + 等待槽(Slot)机制 |
| 典型场景 | 双缓冲、生产消费交换、数据校验 |
如果 Exchanger 中 A 线程发了数据,但是 B 线程没有调用 exchange():
A 会一直阻塞等待 B 到达交换点。
Java 并发同步体系
java.util.concurrent
├── CountDownLatch
│ 等待一次性任务完成
│
├── CyclicBarrier
│ 多线程循环集合
│
├── Phaser
│ 多阶段动态同步
│
├── Semaphore
│ 控制并发数量
│
└── Exchanger
两线程交换数据
