Skip to content

线程间通信方式

在Java多线程编程中,线程间通信(Inter-Thread Communication)是协调多个线程协同工作的核心技术。以下是主要通信方式及其应用:


1. wait()/notify()/notifyAll()

一、是什么?
Object类提供的原生方法:

  • wait():释放锁并阻塞当前线程,等待唤醒。
  • notify():随机唤醒一个等待线程。
  • notifyAll():唤醒所有等待线程。

二、解决什么问题
解决线程在共享资源上的等待/通知问题,避免忙等待(busy-waiting),减少CPU浪费。

三、核心方法

java
synchronized (lock) {
    while (条件不满足) {
        lock.wait(); // 释放锁并等待
    }
    // 执行业务
    lock.notifyAll(); // 唤醒其他线程
}

四、应用场景
生产者-消费者模型(如任务队列)、线程按顺序执行。

五、重要注意事项

  • 必须在synchronized块内调用,否则抛IllegalMonitorStateException
  • 推荐用while代替if检查条件,防止虚假唤醒(spurious wakeup)。

2. Lock与Condition(JDK5+)

一、是什么?
java.util.concurrent.locks.Lock接口替代synchronizedCondition提供更灵活的等待/通知机制。

二、解决什么问题
解决synchronized无法中断、超时等限制,支持多条件队列(如读写锁)。

三、核心方法

java
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();

lock.lock();
try {
    while (条件不满足) {
        condition.await(); // 类似wait()
    }
    // 执行业务
    condition.signalAll(); // 类似notifyAll()
} finally {
    lock.unlock();
}

四、应用场景
复杂同步需求(如阻塞队列实现)、高性能并发控制。

五、重要注意事项

  • 必须手动释放锁(unlock()),通常放在finally块。
  • Condition支持多个等待队列(如生产者/消费者独立唤醒)。

3. 阻塞队列(BlockingQueue)

一、是什么?
java.util.concurrent.BlockingQueue接口,线程安全的队列,提供阻塞式插入/移除。

二、解决什么问题
简化生产者-消费者模型,避免手动实现wait/notify逻辑。

三、核心方法

  • put(E e):队列满时阻塞插入。
  • take():队列空时阻塞移除。

四、应用场景
线程池任务队列、数据管道(如日志处理)。

五、Java示例

java
BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);

// 生产者
queue.put("data"); // 阻塞直到空间可用

// 消费者
String data = queue.take(); // 阻塞直到数据可用

4. 并发工具类(JDK5+)

一、CountDownLatch

  • 是什么? 计数器锁,线程等待其他线程完成。
  • 场景:主线程等待所有子线程初始化完成。
java
CountDownLatch latch = new CountDownLatch(3);
latch.countDown(); // 子线程调用
latch.await();     // 主线程阻塞等待

二、CyclicBarrier

  • 是什么? 循环屏障,线程相互等待至指定数量。
  • 场景:多阶段并行计算(如MapReduce)。

三、Semaphore

  • 是什么? 信号量,控制资源访问并发数。
  • 场景:数据库连接池限流。

5. volatile变量

一、是什么?
轻量级同步机制,保证变量可见性(直接读写主内存)。

二、解决什么问题
解决多线程环境下共享变量的可见性问题(非原子性)。

三、应用场景
状态标志位(如volatile boolean running),双重检查锁定(Double-Checked Locking)。

四、重要注意事项

  • 不保证原子性(如i++需配合synchronized或原子类)。

关键区别

方式特点适用场景
wait/notifysynchronized,基础但易出错简单同步控制
Lock/Condition灵活,支持多条件复杂同步逻辑
BlockingQueue封装线程安全,开箱即用生产者-消费者模型
CountDownLatch一次性等待主线程等待子线程初始化
volatile仅保证可见性,非互斥状态标志、双重检查锁定

总结

  1. 简单同步wait/notifyvolatile标志位。
  2. 复杂同步Lock/Condition或并发工具类。
  3. 解耦生产消费 → 优先用BlockingQueue
  4. 线程协作CountDownLatch/CyclicBarrier
  5. JDK8+优化:优先使用java.util.concurrent包下的类(如CompletableFuture),避免手动实现底层同步。

注意:避免底层wait/notify的复杂性,高并发场景推荐BlockingQueue或并发工具类,减少出错概率并提升可维护性。