Java的wait(), notify()和notifyAll()使用心得

  

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() 方法,唤醒了所有被阻塞的线程,使它们重新进入就绪状态。

相关文章