全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-10 9 分钟 ✍️ juanwangdev

程间通信

多线程协作需要通信机制,实现等待/唤醒、通知/响应等交互。

wait/notify/notifyAll

基本用法

Java
public class WaitNotifyDemo {
    private final Object lock = new Object();
    private boolean ready = false;

    // 等待线程
    public void waitForReady() throws InterruptedException {
        synchronized (lock) {
            while (!ready) {  // 循环检查条件
                lock.wait();  // 释放锁并等待
            }
            // 条件满足后继续执行
        }
    }

    // 通知线程
    public void setReady() {
        synchronized (lock) {
            ready = true;
            lock.notify();   // 唤醒一个等待线程
            // lock.notifyAll();  // 唤醒所有等待线程
        }
    }
}

必须 synchronized:wait/notify/notifyAll 必须在同步代码块中调用,否则抛 IllegalMonitorStateException。

wait vs sleep

特性wait()sleep()
释放锁✅ 释放❌ 不释放
所属类ObjectThread
唤醒方式notify/notifyAll时间到期或 interrupt
使用位置同步代码块任意位置

notify vs notifyAll

方法说明适用场景
notify()随机唤醒一个只有一个等待线程
notifyAll()唤醒所有等待线程多个等待线程

推荐 notifyAll:避免唤醒不合适的线程导致死等。

生产者-消费者模式

Java
public class ProducerConsumer {
    private final Queue<Integer> queue = new LinkedList<>();
    private final int capacity = 10;
    private final Object lock = new Object();

    // 生产者
    public void produce(int item) throws InterruptedException {
        synchronized (lock) {
            while (queue.size() == capacity) {
                lock.wait();  // 缓冲区满,等待
            }
            queue.add(item);
            System.out.println("生产:" + item);
            lock.notifyAll();  // 通知消费者
        }
    }

    // 消费者
    public int consume() throws InterruptedException {
        synchronized (lock) {
            while (queue.isEmpty()) {
                lock.wait();  // 缓冲区空,等待
            }
            int item = queue.poll();
            System.out.println("消费:" + item);
            lock.notifyAll();  // 通知生产者
            return item;
        }
    }
}

while 循环检查条件:防止虚假唤醒,被唤醒后条件可能仍不满足。

Condition(ReentrantLock)

Condition 提比 wait/notify 更灵活的等待/唤醒机制:

Java
public class ConditionDemo {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();
    private final Queue<Integer> queue = new LinkedList<>();
    private final int capacity = 10;

    public void produce(int item) throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() == capacity) {
                notFull.await();  // 等待非满条件
            }
            queue.add(item);
            notEmpty.signal();   // 通知非空条件
        } finally {
            lock.unlock();
        }
    }

    public int consume() throws InterruptedException {
        lock.lock();
        try {
            while (queue.isEmpty()) {
                notEmpty.await();  // 等待非空条件
            }
            int item = queue.poll();
            notFull.signal();     // 通知非满条件
            return item;
        } finally {
            lock.unlock();
        }
    }
}

Condition vs wait/notify

特性Conditionwait/notify
条件数量多个 Condition单个 wait/notify
精确唤醒signal() 唤醒指定条件notifyAll() 唤醒所有
所属ReentrantLocksynchronized

Condition 优势:多个条件独立等待唤醒,避免不相关线程被唤醒。

volatile 通信

volatile 保证可见性,适合简单通信:

Java
public class VolatileDemo {
    private volatile boolean running = true;

    // 工作线程
    public void work() {
        while (running) {  // 读取最新值
            // 工作逻辑
        }
        System.out.println("线程停止");
    }

    // 停止线程
    public void stop() {
        running = false;  // 立即可见
    }
}

volatile 适用:状态标志位、单例双重检查锁。不保证原子性。

join() 等待线程结束

Java
Thread thread = new Thread(() -> {
    // 执行任务
});
thread.start();
thread.join();  // 等待 thread 结束
// join 后继续执行

要点总结

  • wait/notify/notifyAll 用于 synchronized 同步通信
  • wait() 释放锁并等待,sleep() 不释放锁
  • notify() 随机唤醒一个,notifyAll() 唤醒所有
  • 必须在 synchronized 中调用 wait/notify
  • while 循环检查条件防止虚假唤醒
  • Condition 支持多个条件,精确唤醒
  • volatile 保证可见性,适合状态标志
  • join() 等待线程结束

📝 发现内容有误?点击此处直接编辑

← 上一篇 程的生命周期
下一篇 → 锁机制(ReentrantLock 等)
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库