condition.await()
和 object.wait()
都是用于线程间的协调和通信,但是它们有一些区别:
-
关联对象不同:
condition.await()
必须在与之关联的锁(ReentrantLock)上调用,通过lock.newCondition()
创建 Condition 对象。object.wait()
则是在任何对象上调用,通常结合 synchronized 关键字使用。
-
异常抛出:
- 在调用
condition.await()
时需要处理InterruptedException
异常。 - 而在调用
object.wait()
时也需要处理InterruptedException
异常。
- 在调用
-
唤醒方式:
condition.await()
可以被唤醒的方式有signal()
和signalAll()
。object.wait()
可以被唤醒的方式有notify()
和notifyAll()
。
-
虚假唤醒:
- 对于
condition.await()
,虚假唤醒可以通过循环检查等待条件来避免。 - 而对于
object.wait()
,虚假唤醒也应该在循环中检查等待条件。
- 对于
总的来说,condition.await()
提供了更多的灵活性和安全性,因为它必须在一个特定的锁上调用,而且唤醒时可以选择性地唤醒一个或全部等待线程。相比之下,object.wait()
必须在某个对象上调用,同时唤醒时只能选择唤醒全部等待线程或者一个等待线程。
当使用 condition.await()
和 object.wait()
时,下面是一些示例代码来演示它们的区别:
使用 condition.await()
示例代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionAwaitExample {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean isConditionMet = false;
public void awaitCondition() throws InterruptedException {
lock.lock();
try {
while (!isConditionMet) {
condition.await(); // 等待条件满足
}
System.out.println("Condition is met!");
} finally {
lock.unlock();
}
}
public void signalCondition() {
lock.lock();
try {
isConditionMet = true;
condition.signal(); // 发送信号,唤醒等待的线程
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
ConditionAwaitExample example = new ConditionAwaitExample();
Thread waitingThread = new Thread(() -> {
try {
example.awaitCondition();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread signalingThread = new Thread(example::signalCondition);
waitingThread.start();
Thread.sleep(1000); // 确保等待线程先启动
signalingThread.start();
waitingThread.join();
signalingThread.join();
}
}
在上述示例中,awaitCondition()
方法使用 condition.await()
来等待条件 isConditionMet
的满足。signalCondition()
方法使用 condition.signal()
来发送信号,唤醒等待的线程。
使用 object.wait()
示例代码:
public class ObjectWaitExample {
private Object lock = new Object();
private boolean isConditionMet = false;
public void awaitCondition() throws InterruptedException {
synchronized (lock) {
while (!isConditionMet) {
lock.wait(); // 等待条件满足
}
System.out.println("Condition is met!");
}
}
public void signalCondition() {
synchronized (lock) {
isConditionMet = true;
lock.notify(); // 发送信号,唤醒一个等待的线程
}
}
public static void main(String[] args) throws InterruptedException {
ObjectWaitExample example = new ObjectWaitExample();
Thread waitingThread = new Thread(() -> {
try {
example.awaitCondition();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread signalingThread = new Thread(example::signalCondition);
waitingThread.start();
Thread.sleep(1000); // 确保等待线程先启动
signalingThread.start();
waitingThread.join();
signalingThread.join();
}
}
在上述示例中,awaitCondition()
方法使用 lock.wait()
来等待条件 isConditionMet
的满足。signalCondition()
方法使用 lock.notify()
来发送信号,唤醒一个等待的线程。
这些示例演示了如何使用 condition.await()
和 object.wait()
进行线程间的协调和通信。它们展示了两种不同的方式来实现相同的效果,但是注意到 condition.await()
需要在与锁关联的条件上调用,而 object.wait()
则需要在某个对象上调用。
希望这些信息能够帮助你更好地理解 condition.await()
和 object.wait()
的区别。