文章

线程通信-等待通知机制(整合版)

线程通信-等待通知机制(整合版)

本文整合了原有线程通信相关内容(线程间的通信wait/notify思维导图线程间通信知识点补充),并统一为可复习结构。

1. 什么是线程通信

线程通信是多个线程之间协调执行顺序和数据可见性的机制。常见手段包括:

  • wait/notify/notifyAll
  • join
  • CountDownLatch
  • Condition
  • BlockingQueue

2. 轮询通信的问题

最原始的做法是循环判断共享状态(busy waiting),例如不断 while(list.size()!=5)

  • 会持续消耗 CPU。
  • 可能出现延迟大或读到中间态。
  • 代码可维护性差。

3. wait/notify 基本语义

3.1 核心规则

  • wait/notify/notifyAll 必须在 synchronized 保护块内使用。
  • wait() 会释放当前对象监视器锁。
  • notify() 只通知,不会立刻释放锁,真正释放发生在退出同步块后。
  • notifyAll() 可避免“唤醒了错误线程”导致的长期等待。

3.2 推荐写法(防止虚假唤醒)

1
2
3
4
5
6
7
8
synchronized (lock) {
    while (!condition) {
        lock.wait();
    }
    // do work
}


4. wait/notify 与 Condition 对比

  • 对象级:wait/notify,一个监视器一套等待队列。
  • 锁级:Condition,一个 Lock 可创建多个条件队列,控制粒度更细。
1
2
3
Lock lock = new ReentrantLock();
Condition notEmpty = lock.newCondition();
Condition notFull = lock.newCondition();

5. 常见通信工具选择

  • 主线程等多个子任务结束:CountDownLatch
  • 多线程阶段性互等:CyclicBarrier
  • 生产者消费者:BlockingQueue
  • 线程执行顺序编排:ConditionCountDownLatch + 状态机

6. 易错点清单

  • 在同步块外调用 wait/notify
  • if 代替 while 检查条件。
  • 忘记处理中断(InterruptedException)。
  • 锁对象不一致导致“通知不到”。
  • 误以为 notify 之后马上切换线程。

相关阅读

本文由作者按照 CC BY 4.0 进行授权