Java多线程编程:深入解析wait、notify与notifyAll

在Java编程中,多线程是一种常见且强大的技术,能够有效地提高程序的性能。而多线程编程的核心,就是如何处理好线程间的同步与协作。在这其中,wait、notify和notifyAll这三个关键字扮演着至关重要的角色。本文将深入解析wait、notify与notifyAll的原理和用法,帮助读者更好地掌握Java多线程编程。
一、wait、notify与notifyAll的基本概念
在Java中,wait、notify和notifyAll是Object类提供的三种方法,用于实现线程间的同步和协作。它们分别具有以下特点:
1. wait():使当前线程暂停执行,等待其他线程调用该线程的notify()或notifyAll()方法。
2. notify():唤醒一个等待该对象的线程。如果有多个线程等待,则随机唤醒其中一个。
3. notifyAll():唤醒所有等待该对象的线程。
二、wait、notify与notifyAll的用法详解
1. wait()方法的使用
wait()方法的使用非常简单,只需在同步代码块中调用即可。以下是一个示例:
```java
public class WaitDemo {
public static void main(String[] args) {
Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("t1 is waiting...");
lock.wait();
System.out.println("t1 is woken up...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("t2 is waiting...");
lock.wait();
System.out.println("t2 is woken up...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t1.start();
t2.start();
}
}
```
在这个例子中,两个线程t1和t2都调用lock对象的wait()方法。当线程t1或t2执行到wait()方法时,它们会释放lock对象的监视器,并进入等待状态。此时,线程t1和t2将暂停执行,直到另一个线程调用notify()或notifyAll()方法。
2. notify()方法的使用
notify()方法用于唤醒一个等待该对象的线程。以下是一个示例:
```java
public class NotifyDemo {
public static void main(String[] args) {
Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("t1 is waiting...");
lock.wait();
System.out.println("t1 is woken up...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("t2 is waiting...");
lock.wait();
System.out.println("t2 is woken up...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
System.out.println("notify t1...");
lock.notify();
}
}
}
```
在这个例子中,线程t1和t2都调用lock对象的wait()方法。当线程t1执行到notify()方法时,它会随机唤醒一个等待该对象的线程。在这个例子中,线程t2被唤醒,并继续执行。
3. notifyAll()方法的使用
notifyAll()方法用于唤醒所有等待该对象的线程。以下是一个示例:
```java
public class NotifyAllDemo {
public static void main(String[] args) {
Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("t1 is waiting...");
lock.wait();
System.out.println("t1 is woken up...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
System.out.println("t2 is waiting...");
lock.wait();
System.out.println("t2 is woken up...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
System.out.println("notifyAll...");
lock.notifyAll();
}
}
}
```
在这个例子中,线程t1和t2都调用lock对象的wait()方法。当线程t1执行到notifyAll()方法时,它会唤醒所有等待该对象的线程。在这个例子中,线程t1和t2都被唤醒,并继续执行。
三、注意事项
1. wait、notify和notifyAll方法必须使用在同步代码块中。
2. 在使用wait、notify和notifyAll方法时,要注意线程安全问题。
3. 当使用notifyAll方法时,需要注意,唤醒的线程可能会继续执行wait方法,从而导致死锁。
总之,wait、notify和notifyAll是Java多线程编程中非常重要的关键字。掌握这些关键字的用法,对于编写高效、稳定的Java程序具有重要意义。希望本文能帮助读者更好地理解这些概念,并在实际项目中灵活运用。






