Java 中的 wait(), notify() 和 notifyAll() 方法
介绍
在 Java 中,线程是独立执行的,但是在某些情况下,我们希望线程之间能够进行同步和通信。这时,Java 提供了一些同步机制。其中,使用最广泛的机制就是对象的 wait()、notify() 和 notifyAll() 方法。
线程可以通过调用 wait() 方法来等待某个条件的出现,当条件不满足时,线程将被阻塞。而通过调用 notify() 或 notifyAll() 方法,又可以唤醒等待的线程。
wait() 方法
wait() 方法用于使线程等待某个条件的出现,其语法格式为:
public final void wait() throws InterruptedException
wait() 方法必须在 synchronized 块里调用。当一个线程运行到 wait() 时,它会释放对象的锁,并且线程会进入等待状态。直到另一个线程调用此对象上的 notify() 或 notifyAll() 方法,或者超时时间到期,才能继续执行。
notify() 方法
notify() 方法用于唤醒因等待某个条件而阻塞了的线程,其语法格式为:
public final void notify()
notify() 方法必须在 synchronized 块里调用。当某个线程在等待同一个对象的时候,另外一个使用同一个对象的线程调用 notify() 方法时,等待的线程会从 wait() 方法返回,继续执行。
注意:notify() 方法只能唤醒一个等待线程,具体唤醒哪个线程是随机的,不能确定。因为并不知道哪个线程最需要这个通知。
notifyAll() 方法
notifyAll() 方法用于唤醒因等待某个条件而阻塞了的所有线程,其语法格式为:
public final void notifyAll()
notifyAll() 方法必须在 synchronized 块里调用。当某个线程在等待同一个对象的时候,另外一个使用同一个对象的线程调用 notifyAll() 方法时,所有等待的线程会从 wait() 方法中返回,继续执行。
示例一
下面是一个简单的示例,演示了如何使用 wait() 和 notify() 方法来实现线程间的通信:
public class WaitNotifyDemo {
public static void main(String[] args) {
final Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("Thread 1 is waiting...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 is notified.");
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("Thread 2 is running...");
lock.notify();
}
}
});
t1.start();
try {
Thread.sleep(1000); // 等待一秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
在这个示例中,有两个线程 t1 和 t2,它们使用同一个对象 lock 进行同步。线程 t1 在进入 synchronized 块后调用了 wait() 方法,导致线程被阻塞。而线程 t2 调用了 notify() 方法,唤醒了被阻塞的 t1 线程,使它重新进入就绪状态。
示例二
下面是另一个示例,演示了如何使用 wait() 和 notifyAll() 方法来实现线程间的通信:
public class WaitNotifyAllDemo {
public static void main(String[] args) {
final Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("Thread 1 is waiting...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 is notified.");
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("Thread 2 is waiting...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 2 is notified.");
}
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("Thread 3 is running...");
lock.notifyAll(); // 唤醒所有等待的线程
}
}
});
t1.start();
t2.start();
try {
Thread.sleep(1000); // 等待一秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
t3.start();
}
}
在这个示例中,有三个线程 t1、t2 和 t3,它们使用同一个对象 lock 进行同步。线程 t1 和 t2 在进入 synchronized 块后分别调用了 wait() 方法,导致线程被阻塞。而线程 t3 调用了 notifyAll() 方法,唤醒了所有被阻塞的线程,使它们重新进入就绪状态。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java的wait(), notify()和notifyAll()使用心得 - Python技术站