线程通信-等待通知机制(整合版)
线程通信-等待通知机制(整合版)
本文整合了原有线程通信相关内容(线程间的通信、wait/notify思维导图、线程间通信知识点补充),并统一为可复习结构。
1. 什么是线程通信
线程通信是多个线程之间协调执行顺序和数据可见性的机制。常见手段包括:
wait/notify/notifyAlljoinCountDownLatchConditionBlockingQueue
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 - 线程执行顺序编排:
Condition或CountDownLatch+ 状态机
6. 易错点清单
- 在同步块外调用
wait/notify。 - 用
if代替while检查条件。 - 忘记处理中断(
InterruptedException)。 - 锁对象不一致导致“通知不到”。
- 误以为
notify之后马上切换线程。
相关阅读
本文由作者按照 CC BY 4.0 进行授权