在 Java 中,await, signal, 和 signalAll 是 java.util.concurrent.locks.Condition 接口的方法,而 wait, notify, 和 notifyAll 是 Object 类的方法。它们用于线程间的同步和通信,但工作原理和应用场景有所不同。
1. await, signal, 和 signalAll (使用 Condition)
这些方法是在使用 ReentrantLock 等显式锁时使用的。Condition 提供了更灵活的线程等待和通知机制。
代码示例:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionExample {
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private boolean conditionMet = false;
public void awaitCondition() throws InterruptedException {
lock.lock();
try {
while (!conditionMet) {
condition.await(); // 等待条件满足
}
// 条件满足后的处理逻辑
System.out.println("Condition met!");
} finally {
lock.unlock();
}
}
public void signalCondition() {
lock.lock();
try {
conditionMet = true;
condition.signal(); // 唤醒一个等待线程
} finally {
lock.unlock();
}
}
public void signalAllConditions() {
lock.lock();
try {
conditionMet = true;
condition.signalAll(); // 唤醒所有等待线程
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ConditionExample example = new ConditionExample();
Runnable waitTask = () -> {
try {
example.awaitCondition();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
};
Runnable signalTask = () -> {
example.signalCondition();
};
new Thread(waitTask).start();
new Thread(signalTask).start();
}
}
2. wait, notify, 和 notifyAll (使用 Object)
这些方法是 Object 类的方法,用于在同步代码块中等待和通知线程。必须在同步的上下文中使用,即在 synchronized 块中。
代码示例:
public class WaitNotifyExample {
private final Object lock = new Object();
private boolean conditionMet = false;
public void waitCondition() throws InterruptedException {
synchronized (lock) {
while (!conditionMet) {
lock.wait(); // 等待条件满足
}
// 条件满足后的处理逻辑
System.out.println("Condition met!");
}
}
public void notifyCondition() {
synchronized (lock) {
conditionMet = true;
lock.notify(); // 唤醒一个等待线程
}
}
public void notifyAllConditions() {
synchronized (lock) {
conditionMet = true;
lock.notifyAll(); // 唤醒所有等待线程
}
}
public static void main(String[] args) {
WaitNotifyExample example = new WaitNotifyExample();
Runnable waitTask = () -> {
try {
example.waitCondition();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
};
Runnable notifyTask = () -> {
example.notifyCondition();
};
new Thread(waitTask).start();
new Thread(notifyTask).start();
}
}
主要区别
-
锁的类型:
Condition方法 (await,signal,signalAll) 需要显式的ReentrantLock或其他Lock实现。wait/notify/notifyAll是Object类的方法,使用内置的监视器锁。
-
灵活性:
Condition提供了更多的灵活性和功能,例如多个条件对象和更复杂的等待/通知逻辑。wait/notify/notifyAll适用于较简单的同步需求。
-
重入性:
- 使用
ReentrantLock时,锁的重入性是显式管理的,而synchronized块内的锁具有内置的重入性。
- 使用