目录
程等待唤醒机制是多线程编程中用于线程之间协调和通信的一种机制。在多线程环境中,有时候一个线程需要等待某个条件满足,而另一个线程则需要在某个条件满足时通知其他线程。
在Java中,线程等待和唤醒的方法通常是通过
Object
类的wait()
,notify()
, 和notifyAll()
方法来实现的。这些方法必须在同步块或同步方法中使用,因为它们依赖于对象的锁机制。
wait()
后,线程会等待被其他线程通过 notify()
或 notifyAll()
方法唤醒。interrupt()
方法),也可以在等待一定时间后自动唤醒(通过带有超时参数的 wait(long timeout)
方法)。 synchronized (sharedObject) {
while (conditionIsNotMet) {
sharedObject.wait();
}
// 执行等待后的操作
}
notify()
后,被唤醒的线程将尝试重新获得对象的锁。 synchronized (sharedObject) {
// 满足条件后,通知等待的线程
sharedObject.notify();
}
notifyAll() 方法:
notifyAll()
会唤醒所有等待的线程,这样它们都有机会争夺对象的锁。 synchronized (sharedObject) {
// 满足条件后,通知等待的所有线程
sharedObject.notifyAll();
}
在上述代码中,sharedObject
是共享对象,多个线程在这个对象上进行同步。wait()
方法会使线程释放对象的锁,然后等待其他线程唤醒。notify()
或 notifyAll()
方法用于在满足某个条件时通知等待的线程,使其重新竞争锁。
防止虚假唤醒: 在等待的时候,通常需要在循环中检查条件,以防止虚假唤醒。
synchronized (sharedObject) {
while (conditionIsNotMet) {
sharedObject.wait();
}
// 某个条件满足后的操作
}
调用顺序: 调用 wait()
方法的线程会释放对象的锁,而调用 notify()
或 notifyAll()
的线程会尝试重新获得对象的锁。
合理使用 notifyAll()
: 在使用 notifyAll()
时,需要考虑唤醒的线程是否真的需要被唤醒,以避免不必要的性能开销。
避免死锁: 当设计线程等待唤醒机制时,需要注意避免死锁的情况,确保线程能够正确释放和获取锁。
示例代码:
class SharedResource {
private boolean condition = false;
synchronized void waitForCondition() throws InterruptedException {
while (!condition) {
wait();
}
// 某个条件满足后的操作
}
synchronized void signalCondition() {
condition = true;
notifyAll(); // 或 notify(),唤醒等待的线程
}
}
上述代码中,waitForCondition
方法用于等待条件满足,而 signalCondition
方法用于设置条件并唤醒等待的线程。这是一个简单的示例,实际应用中,需要根据具体场景设计合适的等待唤醒机制。
什么情况下会产生StackOverflowError(栈溢出)和OutOfMemoryError(堆溢出)怎么排查-CSDN博客
在多线程中sleep()和wait()的区别(详细)-CSDN博客