Java并发编程之wait、notify、notifyAll的深入剖析与实践

Java并发编程是Java语言中一个重要的组成部分,也是面试中经常被问到的问题。在Java并发编程中,wait、notify和notifyAll是三个非常重要的方法,它们主要用于线程间的通信。本文将深入剖析wait、notify和notifyAll的工作原理,并通过实例代码演示它们在实际开发中的应用。
一、wait、notify和notifyAll的基本概念
在Java中,当线程执行到某个对象的wait方法时,它将释放该对象的监视器锁,然后进入等待状态。当其他线程调用该对象的notify或notifyAll方法时,进入等待状态的线程将会被唤醒。需要注意的是,wait、notify和notifyAll方法必须被声明在synchronized代码块或方法内部。
1. wait方法:使当前线程等待,直到其他线程调用该对象的notify或notifyAll方法。
2. notify方法:唤醒一个在此对象监视器上等待的单个线程。
3. notifyAll方法:唤醒在此对象监视器上等待的所有线程。
二、wait、notify和notifyAll的工作原理
1. wait方法的工作原理:
当线程执行到对象的wait方法时,它会释放该对象的监视器锁,并将当前线程放入等待队列中。当其他线程调用notify或notifyAll方法时,等待队列中的线程将会根据一定的策略被唤醒。
2. notify方法的工作原理:
当线程执行到对象的notify方法时,它会从等待队列中随机选择一个线程唤醒。唤醒的线程将获取该对象的监视器锁,并进入就绪状态,等待CPU调度执行。
3. notifyAll方法的工作原理:
当线程执行到对象的notifyAll方法时,它会唤醒等待队列中的所有线程。唤醒的线程将获取该对象的监视器锁,并进入就绪状态,等待CPU调度执行。
三、wait、notify和notifyAll的实例代码演示
以下是一个使用wait、notify和notifyAll方法的实例代码,演示了生产者-消费者模式:
```java
public class ProducerConsumer {
private static final Object lock = new Object();
private static int count = 0;
public static void main(String[] args) {
Thread producer = new Thread(new Producer(), "Producer");
Thread consumer = new Thread(new Consumer(), "Consumer");
producer.start();
consumer.start();
}
static class Producer implements Runnable {
@Override
public void run() {
while (true) {
synchronized (lock) {
if (count < 10) {
System.out.println(Thread.currentThread().getName() + "生产了:" + count);
count++;
lock.notify();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
static class Consumer implements Runnable {
@Override
public void run() {
while (true) {
synchronized (lock) {
if (count > 0) {
System.out.println(Thread.currentThread().getName() + "消费了:" + count);
count--;
lock.notify();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
```
在上面的代码中,我们定义了一个名为ProducerConsumer的类,其中包含两个内部类Producer和Consumer。Producer代表生产者,它负责生产数据;Consumer代表消费者,它负责消费数据。在main方法中,我们启动了生产者和消费者线程。
在Producer类中,当count小于10时,生产者线程会生产数据,并将count加1。然后,它会调用notify方法唤醒消费者线程。如果count大于等于10,生产者线程将调用wait方法等待。
在Consumer类中,当count大于0时,消费者线程会消费数据,并将count减1。然后,它会调用notify方法唤醒生产者线程。如果count小于等于0,消费者线程将调用wait方法等待。
通过上述实例代码,我们可以看到wait、notify和notifyAll在Java并发编程中的实际应用。
四、总结
wait、notify和notifyAll是Java并发编程中非常重要的方法,它们主要用于线程间的通信。在本文中,我们深入剖析了wait、notify和notifyAll的工作原理,并通过实例代码演示了它们在实际开发中的应用。希望本文能帮助读者更好地理解Java并发编程中的wait、notify和notifyAll方法。





