├── 五、线程通信│ ├── wait / notify│ ├── Condition│ ├── CountDownLatchObjectConditionwait()await()notify()signal()notifyAll()signalAll()ReentrantLocksynchronized wait/notify只能有一个等待队列锁对象 | |-- wait线程1 |-- wait线程2 |-- wait线程3而Condition可以创建多个等待队列ReentrantLock | -- Condition A | | | -- 等待线程 | -- Condition B | -- 等待线程可以精确唤醒不同类型线程。│ ├──SemaphoreSemaphore是 Java JUCjava.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() 尝试获取│ ├──CyclicBarrierCountDownLatch是 Java JUCjava.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 i1;i3;i){new Thread(() - {System.out.println(Thread.currentThread().getName() 执行任务);try {Thread.sleep(1000);} catch(Exception e){}//任务完成latch.countDown();}).start();}//等待所有任务完成latch.await();System.out.println(所有任务完成主线程继续);}}│ ├── PhaserPhaser是 Java JUCjava.util.concurrent提供的多阶段线程同步工具。java.util.concurrent.PhaserJDK 7 引入。让多个线程分阶段执行任务每个阶段完成后等待其他线程然后进入下一阶段。CyclicBarrierCountDownLatch的增强版。CountDownLatch只能等待一次数量固定例如任务1完成 任务2完成 任务3完成 count 0 结束不能重新开始。CyclicBarrier可以循环但是参与线程数量固定而Phaser支持多个阶段支持动态增加/减少线程每个阶段可以执行不同逻辑│ └── ExchangerExchanger是 Java JUCjava.util.concurrent提供的线程间数据交换工具。让两个线程在某个同步点交换数据。线程A 手里有数据A线程B 手里有数据B↓Exchanger↓线程A 得到数据B线程B 得到数据Aexchange() exchange(timeout)交换数据String result exchanger.exchange(hello);import java.util.concurrent.Exchanger; public class Test { public static void main(String[] args) { ExchangerString 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 两线程交换数据